Pourquoi une classe C # peut-elle hériter d'une interface à la fois implicitement et explicitement?

StackOverflow https://stackoverflow.com/questions/253058

Question

Aujourd'hui, je trouve qu'une classe C # peut hériter d'une interface de manière implicite et explicite. Cela me surprend. Si C # fonctionne de cette manière, une instance peut se comporter différemment si elle est référencée différemment.

interface IFoo
{
    void DoSomething();
}

class Foo : IFoo
{
    #region IFoo Members
    public void DoSomething()
    {
        Console.WriteLine("do something implicitly");
    }
    #endregion

    #region IFoo Members
    void IFoo.DoSomething()
    {
        Console.WriteLine("do something explicitly");
    }
    #endregion
}


        Foo f = new Foo();
        f.DoSomething();

        ((IFoo)f).DoSomething();

Le code ci-dessus est exécuté et généré

do something implicitly
do something explicitly

Je pense que cette conception de C # crée une incohérence de comportement. Peut-être est-il obligatoire qu'une classe C # puisse hériter d'une interface de manière implicite ou explicite, mais pas des deux.

Existe-t-il une raison pour laquelle C # est conçu de cette manière?

Était-ce utile?

La solution

Votre exemple ne met pas en œuvre IFoo de manière implicite et explicite. Vous implémentez uniquement IFoo.DoSometing () explicitement. Vous avez une nouvelle méthode sur votre classe appelée DoSomething (). Cela n'a rien à voir avec IFoo.DoSomething, sauf qu'il porte le même nom et les mêmes paramètres.

Autres conseils

Chaque classe qui implémente une interface a un mappage entre les membres de cette classe et les membres de l'interface. Si la classe explicitement implémente un membre d'interface, l'implémentation explicite sera toujours mappée sur l'interface. S'il n'y a pas d'implémentation explicite, une implémentation implicite est attendue et sera mise en correspondance avec l'interface.

Lorsqu'une classe a le même nom de membre et les types associés qu'une interface mais , elle implémente aussi explicitement le membre correspondant pour l'interface, puis la " implicite " de la classe. L'implémentation n'est pas considérée comme une implémentation de l'interface du tout (à moins que l'implémentation explicite ne l'appelle).

En plus des significations différentes dans chaque cas où la classe implémente plusieurs interfaces avec le même nom / type de membre, même avec une seule interface, la classe elle-même est considérée comme ayant une interface implicite pouvant avoir les mêmes membres / types que la seule interface, mais signifie toujours quelque chose de différent.

Cela le rend plus flexible pour les collisions. En particulier, consultez IEnumerator et IEnumerator<T> - ils ont tous deux une propriété Current, mais de types différents . Vous devez utiliser l'implémentation d'interface explicite pour implémenter les deux (et la forme générique étend la forme non générique).

Héritage multiple: Que faire si vous dérivez de deux interfaces définissant la même méthode à des fins différentes?

  interface IMoveable
  {
    public void Act();
  }

  interface IRollable
  {
    public void Act();
  }

  class Thing : IMoveable, IRollable
  {
    //TODO Roll/Move code here

    void IRollable.Act()
    {
      Roll();
    }

    void IMoveable.Act()
    {
      Move();
    }
  }

Les gars, merci pour vos réponses.

Il s'avère que & "; La classe C # peut hériter d'une interface de manière implicite et explicite à la fois &"; est en fait une illusion. En fait, une classe peut hériter d'une interface pour une fois.

Dans la question initiale, le & "DoSomething &"; la méthode semble & "implémenter implicitement &"; interface IFoo (la méthode est en fait générée par VS2008), mais ce n’est pas réellement le cas. Avec l'implémentation explicite de l'interface IFoo, le & Quot; DoSomething & Quot; Cette méthode s'avère être simplement une méthode normale qui n'a rien à voir avec IFoo, sauf avec la même signature.

Je persiste à croire que la conception de C # est délicate et qu’il est facile de l’utiliser par erreur. Dis, j'ai un code comme ça

        Foo f = new Foo();
        f.DoSomething();

Maintenant, je veux le refactoriser en dessous du code. Cela me semble parfaitement correct, mais le résultat de l’exécution est différent.

        Action<IFoo> func = foo => foo.DoSomething();
        func(f);
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top