31 votes

Pourquoi les classes de collections en C# (comme ArrayList) héritent de plusieurs interfaces si l'une de ces interfaces hérite de la dernière ?

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

public class ArrayList : IList, ICollection, IEnumerable, ICloneable

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

14voto

RichardOD Points 19942

OK, j'ai fait quelques 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 ce qui suit :

 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 dans ? Si vous utilisez le réflecteur, vous obtenez les mêmes résultats.

Mise à jour : Si vous ouvrez la DLL dans ILDASM, vous verrez qu'elle dit :

met en œuvre ...deux

met en œuvre ...un.

3voto

Zr40 Points 1538

Les interfaces supplémentaires sont montrées parce qu'elles sont impliquées par IList. Si vous implémentez IList, vous devez également implémenter ICollection et IEnumerable.

2voto

Egil Hansen Points 3999

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

1voto

Marc Points 893

De MSDN ....

Si une classe implémente deux interfaces qui contiennent un membre avec la même signature, alors l'implémentation de ce membre sur la classe fera en sorte que les deux interfaces à utiliser ce membre comme leur implémentation.

L'implémentation explicite est également utilisée pour résoudre les cas où deux interfaces déclarent chacune des membres différents de l'interface même nom, comme une propriété et une méthode :

0voto

shahkalpesh Points 21553

N'acceptez pas ça comme réponse.

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

En l'implémentant dans ArrayList, il devient facile de savoir - quelles interfaces ArrayList implémente plutôt que d'aller dans IList pour découvrir qu'elle implémente ICollection & IEnumerable.

Cela évite d'avoir à faire des allers-retours dans la chaîne d'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 & IEnumerable également. Donc, même si vous écrivez votre propre classe implémentant IList (sans ajouter ICollection, IEnumerable dans la déclaration) - vous verrez qu'elle devra fournir l'implémentation de ICollection & IEnumerable.

Et le raisonnement de Workmad3 est logique.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X