Question

J'utilise le code suivant pour permettre myClass d'utiliser foreach. Mais je suis assez nouveau à la programmation et avoir une certaine difficulté à comprendre le code suivant. J'ai décrit mes problèmes dans les commentaires. Je vous serais reconnaissant de fournir des informations.

    public class MyClass : IEnumerable<string> 
    {  
    //1) What is IEnumerator for?
        // Whats the difference between IEnumerator and IEnumerable
    public IEnumerator<string> GetEnumerator()     
    {
             yield return "first";         
             yield return "second";     
    }      
    //2) What is it for?  It just calls above method 
   IEnumerator IEnumerable.GetEnumerator()
         {
             return GetEnumerator(); 
         } 
    }
   //3) Lastly what benefits I have from implementing genetic interface 
   //IEnumerable<string> instead of just IEnumerable
Était-ce utile?

La solution

  

Quelle est la différence entre IEnumerator et IEnumerable?

La réponse de Jason est bonne, mais je pensais que je venais d'ajouter que je pense à ce sujet. Imaginez que vous avez une séquence:

1, 1, 2, 3, 5, 8, 13, ...

Maintenant, imaginez que vous avez une flèche pointant à une position de cette séquence:

1, 1, 2, 3, 5, 8, 13, ...
         ^

« une flèche » est un objet qui peut faire deux choses. Tout d'abord, il peut vous donner la chose qu'il pointe du doigt. En second lieu, il peut se faire pointer sur la chose suivante.

IEnumerator est une flèche. Il a une propriété, actuelle, qui vous donne la chose qu'il pointe du doigt. Il a une méthode, MoveNext () qui se fait pointer sur la chose suivante.

Comment obtenez-vous une flèche en premier lieu? Vous avez besoin d'une usine de flèche. Vous demandez à l'usine pour une flèche, et il vous donne une flèche qui pointe vers le premier élément de la séquence.

IEnumerable est une usine de flèche. Il a une méthode, GetEnumerator, qui vous donne une flèche au premier élément de la séquence.

Une belle propriété de ce système est que vous pouvez avoir plusieurs flèches pointant vers des endroits différents dans la même séquence.

  

quels sont les avantages de la mise en œuvre interface générique IEnumerable au lieu de simplement IEnumerable?

Supposons que la séquence est d'entiers. Si vous implémentez IEnumerable alors quand vous dites

foreach(int x in mysequence)

ce qui va réellement faire est de convertir l'int dans la séquence à l'objet, la boxe l'entier, puis immédiatement Unbox le dos d'objet entier, en ajoutant une allocation de mémoire complètement inutile à chaque opération. Si le compilateur sait que la séquence est d'entiers alors il peut sauter l'opération de boxe inutile.

Supposons que la séquence est de chaînes. Si vous implémentez IEnumerable<string> alors vous pouvez dire:

string first = mysequence.First();

Si vous n'êtes pas, alors vous avez à dire

string first = (string)mysequence.First();

qui est inutile et source d'erreurs. Plutôt que de demander au compilateur via un casting que le type est une chaîne, vous pouvez simplement garantie que le type est une chaîne en utilisant le système de type.

Autres conseils

  

1) Qu'est-ce que IEnumerator pour? Quelle est la différence entre IEnumerator et IEnumerable?

IEnumerator est une interface qui représente les méthodes que vous énumérons une séquence. La différence entre IEnumerator et IEnumerable est que le premier représente le contrat pour les objets que vous énumérons une séquence, et celle-ci représente le contrat pour les objets qui sont une séquence qui peuvent être dénombrés sur.

public IEnumerator<string> GetEnumerator() {
         yield return "first";         
         yield return "second";     
}      


IEnumerator IEnumerable.GetEnumerator() {
    return GetEnumerator(); 
} 
  

2) Quel est-il? Il appelle la méthode juste au-dessus.

L'ancien représente une mise en œuvre de la méthode GetEnumerator sur le contrat IEnumerable<string>. Ce dernier représente une mise en œuvre explicite de la méthode GetEnumerator sur le contrat IEnumerable. Le problème est que les deux contrats ont une méthode nommée GetEnumerator mais avec différents types de retour de sorte qu'une méthode ne peut pas satisfaire simultanément les deux contrats (toute IEnumerable<T> mise en œuvre de classe doit également mettre en œuvre IEnumerable comme IEnumerable<T> : IEnumerable). Ce dernier appelle la mise en œuvre de IEnumerable<string>.GetEnumerator comme c'est une mise en œuvre sensible qui renvoie un IEnumerator comme IEnumerator<string> : IEnumerator.

  

3) Enfin les avantages que je IEnumerable<string> de la mise en œuvre d'interface générique au lieu de simplement IEnumerable?

Le typage fort. Vous savez que les éléments d'une IEnumerable<string> de séquence sont toutes les instances de String alors que vous ne savez pas que pour IEnumerable et pourrait finir par essayer de jeter un élément de celui-ci à une instance de String quand il ne peut pas être.

Ceci est la déclaration de IEnumerable<T>:

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

Vous avez pas le choix, vous Vous pour implémenter l'interface IEnumerable non générique ainsi. Vous obtiendrez une erreur de compilation si vous omettez la mise en œuvre IEnumerable.GetEnumerator (). C'est des bagages laissés par les jours 1.x .NET où les génériques ne sont pas encore disponible et la période de transition pour .NET 2.0 où il avait besoin pour soutenir Interop avec des assemblages .NET 1.x. Nous sommes coincés avec.

  

1) Qu'est-ce IEnumerator pour?

IEnumerator est la partie réelle de travail avec le MoveNext () et les membres actuels.

  

Quelle est la différence entre IEnumerator et IEnumerable

IEnumerable est l'interface pour une collection de signaux qu'elle a un GetEnumerator ().

  

2) [GetEnumerator non-générique] Qu'est-ce pour? Il appelle juste au-dessus méthode

La méthode non-générique est juste là pour la compatibilité descendante. Notez qu'il est déplacé « hors de vue », autant que possible par l'utilisation de la mise en œuvre explicite. Mettre en œuvre parce que vous devez puis oublier.

  

3) Enfin les avantages que je de mettre en œuvre l'interface génétique     IEnumerable au lieu de simplement IEnumerable

Lorsqu'il est utilisé avec le foreach adavantage est petite, comme foreach tapera la variable moulé en boucle. Il vous permettra d'utiliser var dans le foreach:

foreach (var s in myClassInstance)     // needs `IEnumerable<string>` 
foreach (string s in myClassInstance)  // works with  `IEnumerable` as well 

Mais avec IEnumerable<string> vous avez également une interface de type sécurisé à d'autres domaines, notamment LINQ:

MyClass mc = new MyClass ();
string s = mc.FirstOrDefault();

GetEnumerator a été autour depuis avant les médicaments génériques ont été introduits dans la langue, afin de ne pas casser le code pré-existant, les appels de méthode par défaut par le biais de la mise en œuvre générique.

Avec une énumération générique, le consommateur de votre classe n'a pas besoin de jeter chaque élément à chaîne lorsque itérer.

En ce qui concerne la question 3, voici quelques réponses (pourquoi les génériques d'utilisation?):

Doit-on utiliser Collection générique pour améliorer la sécurité et performance?

En bref, utiliser les collections génériques à chaque fois que vous le pouvez.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top