2016-12-22 3 views
2

J'ai du mal à comprendre l'avantage de IEnumerable. Je comprends que Enumerables permettent à l'exécution d'être reportée à plus tard.Avantage d'Enumerables

Veuillez voir l'exemple ici: https://msdn.microsoft.com/en-us/library/system.collections.ienumerable(v=vs.110).aspx. Dans cet exemple, le tableau est déjà rempli dans la classe principale, puis injecté dans une classe IEnumerable. Par conséquent, cela semble éliminer l'avantage de reporter l'exécution à plus tard. Qu'est-ce que j'oublie ici?

+2

L'avantage est le même que pour * chaque * interface pour fournir le moins d'informations possible à l'appelant. Donc, au lieu de dire à un membre «j'ai besoin d'un tableau pour fonctionner correctement», vous pouvez également dire: «J'ai besoin d'une sorte de collection que je peux énumérer». Cela n'a donc pas d'importance si c'est en fait un tableau, une liste ou même un flux en (infini). – HimBromBeere

+2

'IEnumerable ' est principalement sur la possibilité d'itérer par zéro ou plusieurs instances de 'T' - il n'y a rien d'implicite à propos des énumérables qui permet une exécution différée. Il arrive, cependant, que LINQ fournit un ensemble d'opérateurs qui permettent l'exécution différée sur les énumérables. Ce sont deux choses différentes. – Enigmativity

Répondre

2

La documentation que vous faites référence est simplement une comment pourriez-vous mettre en œuvre, plutôt que la façon la plus efficace. Bien sûr, l'implémentation montrée n'a aucune utilité, puisque comme vous le dites, le tableau est déjà construit et énumérable sur lui-même.

L'exemple est utile au mieux pour montrer comment un type personnalisé peut agir comme une collection, en implémentant IEnumerable. Cette interface très générique peut bien sûr être utilisée pour être appelée à partir d'une variété d'endroits où vous n'avez pas besoin de connaissances spécifiques sur le type de collection, mais cela n'est pas montré dans l'échantillon.

Un énumérateur est utilisé pour itérer sur un ensemble de données du début à la fin. Vous ne pouvez pas lire l'élément précédent car il peut déjà être supprimé (par exemple, un itérateur qui doit télécharger des fichiers très volumineux à partir d'un emplacement distant, vous ne souhaiterez peut-être pas les mettre en cache).

+0

Y at-il un meilleur exemple que vous pouvez recommander, qui montre comment il pourrait être utilisé plus efficacement? Merci – w0051977

+0

Peut-être que [cette documentation sur 'rendement rendement»] (https://msdn.microsoft.com/fr-fr/library/9k7k7cf0.aspx) fait, mais aucune autre source que je peux penser maintenant. –

+0

Un rappel du mot-clé Yield (quelque chose que je n'ai pas utilisé depuis un moment) a été utile ici. Si quelque chose doit agir comme une collection, alors cela devrait sûrement être une collection? – w0051977

0

C'est un choix de conception de reporter ou non l'évaluation, mais n'est pas mandaté par IEnumerable. Certaines requêtes de sortie Linq (comme Où & Select) reportent l'évaluation, contrairement à d'autres collections comme Dictionary ou List.

Vous devriez utiliser un IEnumerable lorsque la seule information dont vous avez besoin de la collection est de pouvoir 'énumérer' les éléments. Supposons que vous souhaitiez implémenter une méthode ToString pour une collection générique, où l'objet a son propre ToString.

Si vous acceptez un IEnumerable au lieu d'un tableau, une liste ou un ensemble peut être passé en argument, sans aucun changement de code.

4

L'objectif principal d'un IEnumerable est pas de reporter l'exécution à plus tard. Le but d'un IEnumerable est de fournir un moyen d'itérer sur les parties d'un objet. Ces parties peuvent être les éléments d'une liste, mais elles peuvent aussi être (par exemple) les caractères d'un string. L'interface IEnumerable existe car toutes les classes qui autorisent l'itération sur ses parties ne sont pas une collection ou une liste (string) et IEnumerable fournit une interface minimale pour y parvenir sans avoir à implémenter un ICollection ou IList complet.

Le consommateur principal et le plus important d'un IEnumerable est la déclaration foreach, qui est là depuis le début de temps .NET. Ce n'est que plus tard que LINQ est apparu avec la classe Enumerable qui s'appuie également sur l'interface IEnumerable (ou plus précisément sur l'interface IEnumerable<T>).

En parlant de LINQ, l'exécution différée à laquelle vous faites référence dans votre question est en effet une caractéristique clé de LINQ. Cela signifie qu'une requête que vous définissez n'est pas exécutée jusqu'à ce que l'itération du IEnumerable soit effectuée. Cela vous permet d'affiner davantage vos requêtes avant de les exécuter.

Cette exécution différée mais seulement fait référence à comment leIEnumerableest utilisé, pas ce qu'il fait. exécution différée signifie que vous ne commencez à itérer sur la IEnumerable lors de la définition, mais à un autre endroit dans le programme, par exemple un foreach, un ToList etc.

+2

Je ne suis pas sûr que 'string' soit un très bon contre-exemple. Un 'string' n'est rien de plus qu'un tableau de' char's. Sinon, vous êtes sur place pour le reste. – gmiley

+0

@gmiley - C'est ce que dit Sefe. Il fait remarquer qu'une 'chaîne' est une énumérable de' char'. Il a raison – Enigmativity

+1

@gmiley: Une chaîne n'est en fait pas la même chose qu'un tableau de caractères (même si le stockage interne est dans un 'char []'). La principale différence est que 'char []' est un 'IList', alors que' string' ne l'est pas. C'est pourquoi j'ai choisi cet exemple, car 'string' est _only_ et' IEnumerable', pas même un 'ICollection'. – Sefe

1

Un exemple de IEnumerable est l'exécution tardive.

Je chose que le bigs avantage d'utiliser un IEnumerable sont:

  1. Vous pouvez itérer une collection sans savoir comment itérer il (ne la collection ont un indexeur Comment dois-je itérer un arbre? etc.).

  2. Vous pouvez itérer une partie d'une collection - Pensez à trouver le premier élément correspondant à votre condition. Exécution tardive - Vous pouvez filtrer les collections et le véritable filtrage se produira dès que vous traverserez votre IEnumerable (en utilisant ForEach \ ToList etc.).

+0

@HimBromBeere Non. Mais avant d'avoir l'interface IEnumerable, vous devez savoir comment itérer les collections et autres classes qui sont énumérables. –

+1

Le polymorphisme est important. Donc +1 pour le point un. – w0051977