Pourquoi les classes de collections en C # (comme ArrayList) héritent-elles de plusieurs interfaces si l'une de ces interfaces hérite des autres?

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

Question

Lorsque j'appuie sur f12 sur le mot clé ArrayList pour accéder aux métadonnées générées à partir de vs2008, j'ai constaté que la déclaration de classe générée était la suivante

public class ArrayList : IList, ICollection, IEnumerable, ICloneable

Je sais que IList hérite déjà de ICollection et IEnumerable, alors pourquoi ArrayList hérite-t-il de manière redondante de ces interfaces?

Était-ce utile?

La solution

OK, j'ai fait des recherches. Si vous créez la hiérarchie suivante:

  public interface One
    {
        void DoIt();
    }

    public interface Two : One
    {
        void DoItMore();
    }

    public class Magic : Two
    { 
        public void DoItMore()
        {
            throw new NotImplementedException();
        }

        public void DoIt()
        {
            throw new NotImplementedException();
        }
    }

Et compilez-le, puis référencez la DLL dans une solution différente, tapez Magic et appuyez sur F12, vous obtiendrez les éléments suivants:

 public class Magic : Two, One
    {
        public Magic();

        public void DoIt();
        public void DoItMore();
    }

Vous verrez que la hiérarchie des interfaces est aplatie ou que le compilateur ajoute les interfaces? Si vous utilisez un réflecteur, vous obtenez également les mêmes résultats.

Mise à jour: si vous ouvrez la DLL dans ILDASM, vous la verrez ainsi:

implémente ... Deux

implémente ... Un.

Autres conseils

Les interfaces supplémentaires sont affichées car elles sont impliquées par IList. Si vous implémentez IList, vous devez également implémenter ICollection et IEnumerable.

Je ne fais que deviner, mais je pense qu'en réalité, il implémente seulement IList dans le code, mais la documentation montre également le reste des interfaces pour le rendre explicite au programmeur qui utilise la classe.

De MSDN ....

  

Si une classe implémente deux interfaces   qui contiennent un membre avec le même   signature, puis la mise en œuvre   membre de la classe causera à la fois   interfaces pour utiliser ce membre en tant que leur   la mise en oeuvre.

     

L'implémentation explicite est également utilisée   pour résoudre les cas où deux interfaces   déclarent chacun des membres différents du   même nom tel qu'une propriété et un   méthode:

N'acceptez pas cela comme réponse.

Je répète ce que workmad3 a dit plus haut.

En l'implémentant dans ArrayList, il est facile de savoir - les interfaces implémentées par ArrayList plutôt que de rechercher IList pour savoir qu'il implémente ICollection & amp; IEnumerable.

Cela évite d'avoir à revenir en arrière & amp; vient la chaîne de l'héritage.

EDIT: Au niveau de base, une interface implémentant une autre interface ne peut pas fournir l’implémentation. La classe dérivée (de IList) implémente donc indirectement ICollection & amp; IEnumerable aussi. Ainsi, même si vous écrivez votre propre classe implémentant IList (et que vous n’ajoutez pas ICollection, IEnumerable dans la déclaration), vous verrez qu’elle devra fournir l’implémentation pour ICollection & amp; IEnumerable.

Et le raisonnement de workmad3 est logique.

Je pense que le CLR ne prend pas en charge une interface héritant d'une autre interface.

C # supporte cependant cette construction mais doit "aplatir" l'arbre d'héritage pour qu'il soit conforme au CLR.

[Modifier]

Après avoir pris conseil ci-dessous, configurez rapidement un projet VB.Net:

Public Interface IOne
    Sub DoIt()
End Interface

Public Interface ITwo
    Inherits IOne
    Sub DoIt2()
End Interface

Public Class Class1
    Implements ITwo

    Public Sub DoIt() Implements IOne.DoIt
        Throw New NotImplementedException()
    End Sub

    Public Sub DoIt2() Implements ITwo.DoIt2
        Throw New NotImplementedException()
    End Sub
End Class

La compilation des résultats dans les éléments suivants (C #):

public class Class1 : ITwo
{
    public Class1();
    public void DoIt();
    public void DoIt2();
}

Cela montre que VB.Net NOT n'aplatit pas la hiérarchie des interfaces, contrairement à C #. Je ne sais pas pourquoi cela se produirait.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top