2010-10-03 13 views
2

Je suis en train d'apprendre les interfaces. J'ai lu des livres/articles et jusqu'ici tout va bien - j'ai écrit quelques exemples d'interfaces. Yay :)À quoi ressemble le code source de IEnumerable?

Maintenant, j'ai remarqué que l'une des interfaces C# les plus populaires est l'interface IEnumerable. Il est beaucoup utilisé pour toutes sortes de collections, etc.

Quoi qu'il en soit, je voudrais l'examiner, avec l'intention de mieux comprendre comment cela fonctionne réellement. J'ai cherché Google, mais je ne peux pas trouver une référence au code source réel, mais j'imagine que ce serait contenir l'interface elle-même, et une classe (es) contenant les diverses méthodes.

Alors, quelqu'un peut-il aider?

Très appréciée

Répondre

7

IEnumerable est assez simple:

[ComVisibleAttribute(True)] 
[GuidAttribute("496B0ABE-CDEE-11d3-88E8-00902754C43A")] 
public interface IEnumerable 
{ 
    IEnumerator GetEnumerator(); 
} 

Et pour être complet, IEnumerator

[ComVisibleAttribute(true)] 
[GuidAttribute("496B0ABF-CDEE-11d3-88E8-00902754C43A")] 
public interface IEnumerator 
{ 
    Object Current {get;} 
    bool MoveNext(); 
    void Reset(); 
} 

Mais le plus souvent ce que vous voyez vraiment des exemples de code est IEnumerable<T>

public interface IEnumerable<out T> : IEnumerable 
{ 
    IEnumerator<T> GetEnumerator(); 
    IEnumerator GetEnumerator(); //inherited from IEnumerable 
} 

Et encore une fois pour être complet, IEnumerator<T> (avec IDisposable):

public interface IEnumerator<out T> : IDisposable, IEnumerator 
{ 

    void Dispose(); //inherited from IDsiposable 
    Object Current {get;} //inherited from IEnumerator 
    T Current {get;} 
    bool MoveNext(); //inherited from IEnumerator 
    void Reset(); //inherited from IEnumerator 
} 

[ComVisibleAttribute(true)] 
public interface IDisposable 
{ 
    void Dispose(); 
} 

C'est vraiment tout ce qu'il ya à faire. Il n'y a pas de code d'implémentation directe pour tout ce qui est spécifique à IEnumerable ou le code affiché ici. Plutôt, les types comme les tableaux ou la liste < T> hériteront de IEnumerable et implémenteront les méthodes requises. Tout le reste est effectué via extension methods.

Ce qui rend tous ces éléments sont encore plus puissants:

  1. C# 'prend en charge KEYWORD foreach en boucle sur quoi que ce soit qui a une méthode GetEnumerator() qui retourne un IEnumerator, et vous pouvez donc utiliser tout type qui implémente IEnumerable avec une boucle foreach.
  2. La syntaxe de compréhension de requête linq fonctionne de manière similaire, de sorte que vous pouvez utiliser la plupart des objets IEnumerable avec linq to. Le mot clé yield vous permet de créer quelque chose appelé iterator blocks. Les blocs d'itérateur ont des propriétés intéressantes (comme l'évaluation paresseuse) et vous permettent de créer facilement vos propres types IEnumerable sans avoir à se donner la peine de définir une nouvelle classe en premier.

Enfin, il est intéressant de souligner ici que IDisposable est une autre interface vaut une étude plus approfondie, car il est utilisé tout à fait un peu dans le cadre et a prise en charge linguistique directe similaire à foreach de IEnumerable avec le mot-clé using.

+0

Merci beaucoup pour cela, ma prochaine question sera probablement liée à IDisposable :) – Marko

+0

Il est également intéressant d'ajouter un détail mineur ici que tandis que 'IEnumerable' n'hérite pas de' IDisposable' (contrairement à 'IEnumerable ' qui le fait), le code de 'foreach' fera l'équivalent de' if (énumérateur est IDisposable) {((IDisposable) énumérateur) .Dispose();} 'donc ces objets seront toujours éliminés si possible. L'ajout du support 'IDisposable' quand' IEnumerable 'a été créé rendait le codeur plus efficace et plus explicite, mais la fonctionnalité équivalente était toujours là. –

+0

En ce qui concerne la "source" que vous montrez pour les interfaces génériques: Tous les membres où vous mettez un commentaire "hérité de ..." ne seront pas réellement dans la source. Ensuite, la méthode 'GetEnumerator()' aura le mot clé 'new' car elle cache une méthode avec la même signature à partir de l'interface de base. Et la même chose avec la propriété 'Current'; il cache une propriété avec le même nom à partir de son interface de base. –

1

Les interfaces ne contiennent pas de code.

+3

Ils ne contiennent pas d'implémentations, ils contiennent du code. –

+0

Donc vous dites que les méthodes intégrées pour IEnumerable sont vides? – Marko

+5

@Marko, c'est une interface. Une définition d'un contrat, rien de plus. * Vous * fournissez les implémentations. –

6

IEnumerable<T> est simplement une interface qui définit:

public interface IEnumerable<T> : IEnumerable 
{ 
    // Methods 
    IEnumerator<T> GetEnumerator(); 
} 

La plupart des méthodes que je suppose que vous voulez enquêter viennent d'un tas de méthodes d'extension qui vivent principalement dans l'espace de noms System.Linq dans System.Core.dll. Jetez un oeil avec Reflector.

+0

Merci spender, je vais télécharger Reflector et commencer à enquêter. C'est tout ce dont j'avais besoin! :) – Marko

1

Recherchez-vous.

Téléchargez Reflector et utilisez-le pour parcourir le framework .NET lui-même.

réflecteur peut vous montrer ce que la source de IEnumerable, IEnumerable<T> et Enumerable ressemble, dans votre choix de la langue (il peut décompiler à C# ou VB ou Delphi ou ...)

0

vous devez d'abord comprendre la conception modèle sous la mise en œuvre de toute interface, alors vous pourriez profondément le comprendre. L'interface IEnumerable implemenet Iterator modèle de conception. Parfois, vous utiliserez Iterator avec Composite modèle

+0

Je ne comprends pas pourquoi j'ai -1 vote? – coolkid

+0

Comment est-ce que IEnumerable est lié à un pattern Composite? À ma connaissance, les classes Composite et child/leaf du Composite doivent partager une interface commune. – smartcaveman

+0

oui, je réponds si vite, donc j'oublie de l'examiner. De plus, chaque fois que j'utilise un pattern Composite, j'utilise aussi IEnumerable. Donc, je pense à la hâte qu'ils se rapportent. Je vais éditer ma réponse, merci pour le commentaire – coolkid

0

Notez le Mono Implementation (je vous recommande de vérifier dehors, et d'utiliser un outil de recherche pour rechercher ClassName.cs car il peut être un peu difficile de trouver des choses) est bon pour regardant le code source

Microsoft publie également le code source en tant que source partagée (regardez mais ne touchez pas/ne copiez pas) copie de .net mais je resterais loin de lui surtout si vous pourriez réimplémenter une partie ou implémenter des classes similaires.