79 votes

Distinction entre itérateur et énumérateur

Une question d'entrevue pour un .NET 3.5 emploi est "Quelle est la différence entre un itérateur et un agent recenseur"?

C'est une base de la distinction à faire, ce qui avec LINQ, etc.

De toute façon, quelle est la différence? Je n'arrive pas à trouver une solide définition sur le net. Ne vous méprenez pas, je peux trouver la signification des deux termes, mais je reçois des réponses légèrement différentes. Quelle serait la meilleure réponse pour un entretien?

IMO un interator "itérations" sur une collection, et un agent recenseur fournit la fonctionnalité de réitérer, mais cela doit être appelé.

Aussi, en utilisant le mot clé yield est dit pour économiser de l'état. Quel est exactement cet état? Est-il un exemple de cette prestation présentes?

Merci

60voto

Daniel Brückner Points 36242

L'itération des moyens de répéter certaines étapes, lors de l'énumération des moyens de passer par toutes les valeurs dans un ensemble de valeurs. Si l'énumération de nécessite généralement une certaine forme d'itération.

De cette façon, l'énumération est un cas particulier de l'itération où l'étape est l'obtention d'une valeur à partir d'une collection.

Notez le "généralement" – l'énumération peut également être réalisée de manière récursive, mais la récursivité et itération sont si étroitement liées que je ne serais pas se soucier de cette petite différence.

Vous pouvez également énumérer les valeurs que vous n'avez pas stocker explicitement dans une collection. Par exemple, vous pouvez énumérer le nombre naturel, nombres premiers, ou que ce soit, mais vous pouvez calculer ces valeurs lors de l'énumération et de ne pas les récupérer à partir d'une collection physique. Vous comprenez ce cas que l'énumération d'une collection virtuelle avec ses valeurs définies par une certaine logique.


Je suppose Reed Copsey a obtenu le point. En C# il y a deux principales façons d'énumérer quelque chose.

  1. Mettre en oeuvre Enumerable et d'une classe implémentant IEnumerator
  2. Mettre en œuvre un itérateur avec l' yield déclaration

La première méthode est plus difficile à mettre en œuvre et utilise des objets de l'énumération. La deuxième façon est plus facile à mettre en œuvre et utilise les suites.

46voto

Reed Copsey Points 315315

En C# 2+, les itérateurs sont une façon pour le compilateur pour générer automatiquement l'interface IEnumerable et/ou IEnumerable<T> interfaces pour vous.

Sans itérateurs, vous devez créer une classe implémentant IEnumerator, y compris l'Actuel, MoveNext, et la Réinitialisation. Cela nécessite une bonne quantité de travail. Normalement, vous devez créer une classe privée qui implemtented IEnumerator<T> pour votre type, puis yourClass.GetEnumerator() serait de construire privé de classe, et de le retourner.

Les itérateurs sont une façon pour le compilateur pour générer automatiquement pour vous, en utilisant une syntaxe simple (rendement). Cela vous permet de mettre en œuvre GetEnumerator() directement dans votre classe, sans une seconde classe (Le IEnumerator) étant spécifié par vous-même. La construction de cette classe, avec l'ensemble de ses membres, est fait pour vous.

Les itérateurs sont très développeur convivial de faire les choses dans une manière très efficace, avec beaucoup moins d'effort.

Lorsque vous utilisez foreach, les deux vont se comportent de façon identique (à condition que vous écrivez votre propre IEnumerator correctement). Les itérateurs seulement rendre la vie beaucoup plus simple.

21voto

cdiggins Points 5549

Ce que le C# appelle un itérateur est le plus souvent (en dehors de la C# monde), appelé générateur ou générateur de fonction (par exemple en Python). Un générateur de fonction est un cas spécial de la coroutine. Un itérateur C# (générateur) est une forme particulière d'un agent recenseur (un type de données de la mise en œuvre de l' IEnumerable interface).

Je n'aime pas cette utilisation du terme itérateur pour un C# générateur parce que c'est tout autant un agent recenseur, comme il est un itérateur. Trop tard pour Microsoft pour modifier son esprit.

Pour le contraste considérer qu'en C++, un itérateur est une valeur qui est utilisée principalement pour l'accès séquentiel des éléments dans une collection. Il peut être avancé, derferenced pour récupérer une valeur, et testé pour voir si la fin de la collecte a été atteint.

12voto

Joshua Points 797

Pour comprendre les itérateurs nous avons d'abord besoin de comprendre des agents recenseurs.

Les agents recenseurs sont des objets qui fournissent un avec les moyens de vous déplacer dans une liste ordonnée d'éléments à la fois (le même genre de chose est parfois appelé un "curseur"). L' .NET framework fournit deux interfaces relatives aux agents recenseurs: IEnumerator et IEnumerable. Des objets qui mettent en œuvre IEnumerator sont eux-mêmes des agents recenseurs; ils soutiennent les membres suivants:

  • la propriété Actuelle, qui pointe à une position sur la liste

  • la méthode MoveNext, qui déplace l'élément Courant l'un sur la liste

  • la méthode de Réinitialisation, qui déplace l'élément sélectionné à sa position initiale (qui est avant le premier élément).

D'autre part, les Itérateurs de mettre en œuvre l'énumérateur modèle. .NET 2.0 a introduit l'itérateur, qui est а compilateur manifesté agent recenseur. Lorsque l'objet énumérable appels GetEnumerator, que ce soit directement ou indirectement, le compilateur génère et renvoie un approprié itérateur objet. En option, l'itérateur peut être а combiné énumérable et de l'objet énumérateur.

L'ingrédient essentiel d'un bloc itérateur est le rendement de l'énoncé. Il y a une grande différence entre les itérateurs et les agents recenseurs: les Itérateurs ne pas mettre en œuvre la méthode de Réinitialisation. L'appel de la méthode Reset sur un itérateur provoque une exception.

Le point de itérateurs est de permettre la mise en œuvre facile des agents recenseurs. D'où une méthode doit retourner un agent recenseur ou une énumération de la classe pour une liste ordonnée d'éléments, il est écrit de façon à revenir chaque élément dans son bon de commande, en utilisant le "rendement" de la déclaration.

9voto

richard Points 3579

Puisque aucun des exemples ont été donnés, en voici un qui a été utile pour moi.

Un agent recenseur est un objet que vous obtenez lorsque vous appelez .GetEnumerator() sur une classe ou d'un type qui implémente l'interface IEnumerator. Lorsque cette interface est implémentée, vous avez créé tout le code nécessaire pour le compilor pour vous permettre d'utiliser foreach de "itérer" sur votre collection.

Qui n'est pas le mot "itérer" confondu avec itérateur bien. À la fois l'agent Recenseur et l'itérateur permet de "itérer". L'énumération et l'itération sont essentiellement le même processus, mais sont mis en œuvre différemment. L'énumération des moyens que vous avez impleneted l'interface IEnumerator. L'itération signifie que vous avez créé l'itérateur de construire dans votre classe (illustré ci-dessous), et vous vous appelez foreach sur votre classe, date à laquelle le compilor crée automatiquement l'agent recenseur fonctionnalité pour vous.

Notez également que vous n'avez pas à faire de squat avec votre agent recenseur. Vous pouvez appeler MyClass.GetEnumerator() tout au long de la journée, et ne rien faire avec elle (exemple:

IEnumerator myEnumeratorThatIWillDoNothingWith = MyClass.GetEnumerator()).

Notez aussi que votre itérateur construire dans votre classe uniquement vraiment utilisé lorsque vous êtes réellement l'utiliser, c'est à dire vous dites foreach sur votre classe.

Voici un itérateur exemple à partir de msdn:

public class DaysOfTheWeek : System.Collections.IEnumerable
{

     string[] days = { "Sun", "Mon", "Tue", "Wed", "Thr", "Fri", "Sat" };

     //This is the iterator!!!
     public System.Collections.IEnumerator GetEnumerator()
     {
         for (int i = 0; i < days.Length; i++)
         {
             yield return days[i];
         }
     }

}

class TestDaysOfTheWeek
{
    static void Main()
    {
        // Create an instance of the collection class
        DaysOfTheWeek week = new DaysOfTheWeek();

        // Iterate with foreach - this is using the iterator!!! When the compiler
        //detects your iterator, it will automatically generate the Current, 
        //MoveNext and Dispose methods of the IEnumerator or IEnumerator<T> interface
        foreach (string day in week)
        {
            System.Console.Write(day + " ");
        }
    }
}
// Output: Sun Mon Tue Wed Thr Fri Sat

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