Question

J'ai refacturé la base de code du projet sur lequel je suis actuellement, afin que les classes / interfaces qui ne sont pas utiles au-delà des limites de l'assembly soient déclarées comme internes (plutôt que publiques). Mais j'ai rencontré un problème avec le code suivant:

internal interface IFirstInterface
{
    ...
}

internal interface ISecondInterface
{
    IFirstInterface First{ get; }
    ...
}

public class Implementer : ISecondInterface
{
    public IFirstInterface First {get; private set;}
    ...
}

Mes questions:

  1. Pourquoi les membres des interfaces internes doivent-ils être implémentés publiquement? Si vous implémentez l'interface sur une classe interne, les membres implémentés ne devraient-ils pas être internes? Ce n'est pas un gros problème car les membres de l'interface ne seront de toute façon pas accessibles au public, étant donné que la classe est interne. Cela semble tout simplement contre-intuitif.

  2. Le problème principal concerne le scénario ci-dessus, car je ne peux pas utiliser de getter public pour IFirstInterface, car il s'agit d'une interface interne, c'est-à-dire que je reçois l'erreur suivante du compilateur:

  

Accessibilité incohérente: propriété   type 'IFirstInterface' est moins   accessible que la propriété   "Implementer.First"

Y at-il un moyen de contourner cela?

Remarque : je me rends compte que cet exercice de refactoring a probablement peu de valeur, mais j’ai pensé que ce serait un bon moyen pour moi de comprendre plus en profondeur les implications du modificateur interne.

Était-ce utile?

La solution

Remarque: le code que vous avez réellement fourni est compilé , car Implementer est une classe interne. Le problème survient lorsque Implementer est public.

La solution consiste à utiliser une implémentation d'interface explicite:

public class Implementer : ISecondInferface
{
    private IFirstInterface first;
    IFirstInterface ISecondInterface.First { get { return first; } }
}

Vous ne pouvez pas avoir le setter ici, car vous implémentez explicitement l'interface qui ne définit pas le setter. Vous pouvez le faire comme alternative:

public class Implementer : ISecondInterface
{
    internal IFirstInterface First { get; private set; }
    IFirstInterface ISecondInterface.First { get { return First; } }
}

Il est regrettable que les interfaces internes aient des membres publics - cela complique les choses comme ceci. Il serait étrange qu'une interface publique ait un membre interne (en quoi cela serait-il interne: l'implémenteur ou le déclarant?), Mais pour les interfaces internes, cela a beaucoup plus de sens.

Autres conseils

  

Pourquoi les membres des interfaces internes doivent-ils être implémentés publiquement?

Lorsque vous définissez une interface, vous ne définissez pas le niveau d'accès des membres, car tous les membres de l'interface sont public . Même si l'interface en tant que telle est internal , les membres sont toujours considérés comme public . Lorsque vous effectuez une implémentation implicite d'un tel membre, la signature doit correspondre, elle doit donc être public .

Concernant l'exposition du getter, je suggèrerais plutôt d'implémenter une implémentation explicite de l'interface et de créer une propriété interne pour afficher la valeur:

internal IFirstInterface First { get; private set; }

IFirstInterface ISecondInterface.First
{
    get { return this.First; }
}

Je sais que ce message date de quelques années, mais j'estime qu'il est utile de noter que vous pouvez implémenter une interface interne sur une classe publique, voir les liens suivants:

   http://forums.create.msdn.com/forums/p/29808/ 167820.aspx
   http://msdn.microsoft.com/en-us/ bibliothèque / aa664591% 28VS.71% 29.aspx

Un exemple du premier lien:


internal interface ISecretInterface
{
    string Property1 { get; }
}

public class PublicClass : ISecretInterface
{
    // class property
    public string Property1
    {
        get { return "Foo"; }
    }

    // interface property
    string ISecretInterface.Property1
    {
        get { return "Secret"; }
    }
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top