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:
- 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.
- 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
.
Merci beaucoup pour cela, ma prochaine question sera probablement liée à IDisposable :) – Marko
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à. –
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. –