Ayons ce code:
MyList list = new MyList();
foreach (int i in list)
{
Console.WriteLine(i);
}
foreach (int i in list)
{
Console.WriteLine(i);
}
6 Réponses :
La réinitialisation n'est pas appelée par Les classes .NET, comme Par exemple < code> ArrayList code> Implements donc il y a donc Pas besoin de s'inquiéter de l'appel de la réinitialisation car chaque foreach utilise une nouvelle instance de l'énumérateur. P> Pour un exemple complet montrant la mise en œuvre d'ienumerator iEnumerable et une classe distincte, vous pouvez regarder la documentation pour iEnumerable . p> p> foreach code>. En regardant votre méthode principale dans le réflecteur, confirme cela. ArrayList code>, renvoient réellement une nouvelle instance d'une classe qui implémente Ienumerator. P> iEnumerable code> et son getenumerator code> La méthode ressemble à ceci: p>
L'iénumérable et l'iéenumerator doit généralement être des cours distincts, et sauf dans le cas d'énumérateurs qui retournent toujours vide ou de retourner toujours le même élément, la méthode Getenumerator doit toujours renvoyer une nouvelle instance d'un ienumerator. p>
Il n'y a pas beaucoup de point sur ienumerator.Reset; Pour chaque boucle ne l'utilise pas, et les consommateurs d'un iénumérateur / ienumerator ne peuvent pas l'utiliser à moins qu'ils ne sachent que le type énumérable est, auquel cas ils pouvaient utiliser le type réel plutôt que l'interface. P>
Et si quelqu'un implémente la méthode MOVENNTEXT de telle manière que lorsqu'il s'agisse de revenir avec FALSE, avant que cette réinitialisation de cet appel soit une mauvaise pratique? Et si oui, pourquoi ils ont mis la réinitialisation dans l'interface?
@ jannagy02: Il existe un certain nombre d'aspects de .NET qui doivent être considérés comme des produits vestigaux d'évolution / ou de compromis. Certains n'ont jamais été bien pensés; D'autres ont peut-être été des pièces sensibles et utiles à une étape de la conception, mais rendu inutile lorsque d'autres parties de la conception retravaillaient. Parfois, les choses évoluent dans le processus de conception, même les personnes impliquées dans une conception pourraient ne pas se souvenir de quelles parties ont été pensées à travers et lesquelles étaient jetées ensemble.
réinitialisation est redondant; tellement de sorte qu'il s'agisse d'une exigence em> dans la spécification de langue pour les blocs d'itérateur pour lancer une exception à la réinitialisation. La bonne chose à faire est simplement d'éliminer et de libérer l'ancien itérateur et d'appeler à nouveau Getenumerator. Ou mieux: Évitez avoir em> pour le lire deux fois, car toutes les données ne sont pas répétables. P>
Avez-vous un lien vers où il est dit qu'une exception devrait être lancée? J'aimerais lire cela.
Hmmm ... trouvé Ce . Apparemment, réinitialiser code> n'existe que pour l'interopérabilité COM. Il me semble que cela n'aurait jamais dû être défini sur l'interface en premier lieu.
La réinitialisation ne serait pas redondante s'il était mieux défini. S'il y avait un «général» iéalérable et une imultipasseneutable qui en héritée et renvoyait un imultipassenumerator, qui a mis en œuvre la réinitialisation, il pourrait alors avoir la sémantique qui a répété que les énumérations à l'aide du même énumérateur seraient garantis pour renvoyer les mêmes résultats, même si le la collecte a été modifiée; En revanche, si on tente d'utiliser deux énumérateurs distincts une fois chacun, ils pourraient très bien renvoyer différents résultats.
@supercat je ne suis pas en désaccord, mais: il n'y a pas: P
Cela fonctionne également:
public bool MoveNext()
{
if(i < 5)
{
i++;
return true;
}
else
{
i = -1;
return false;
}
}
Il y a beaucoup d'instances où je dois faire cela, alors ce que je fais est une réinitialisation d'appel dans ma méthode getenumerator. Voici un exemple:
La réponse acceptée est beaucoup mieux; Vous ne devriez tout simplement pas avoir votre ienumerable code> renvoyer la même instance de ienumerator code> à chaque fois. En utilisant cette approche, vous ne pouvez pas jamais i> avoir deux itérateurs différents itérant la même liste. L'utilisation d'une implémentation appropriée ayant plusieurs itérateurs n'est pas un problème du tout.
C'est un bon point. Ma réponse était plus directe à la question initiale qui itérit la collection deux fois séparé.
Pendant que je suis d'accord avec les commentaires concernant des pièces vestigiales et que Considérez une énumération complexe, construite en composant des centaines de «décorateurs» différents . Le coût de la construction d'un tel objet est non négligeable. Nous considérons maintenant également la source de cette énumération complexe est dynamique, mais pour des raisons de traitement, des sémantiques d'instantané sont nécessaires. Dans un tel scénario, nous pouvons créer cette «pile d'énumérateur» et sur le premier J'ai trouvé beaucoup d'utilisations pour utiliser des énumérateurs réinitialisables et c'est presque toujours dans Relation à une sorte de flux de données nécessitant des décorateurs d'énumérateurs complexes / compostables. Dans beaucoup de ces décorateurs, l'appel à ci-dessous est un exemple d'un énumérateur source qui télécharge un document une liste, puis énumère sur cette liste. La réinitialisation de l'énumérateur provoque la ré-téléchargée de la liste. En outre, un énumérateur de décorateur est défini pouvant être utilisé pour envelopper l'énumérateur de la liste (ou tout énumérateur) pour projeter les éléments de l'énumérateur. Je l'ai appelé réinitialiser () code> n'est pas utilisé par le code-cadre et les blocs de générateur offrent effectivement des exceptions, je ne suis pas d'accord que c'est complètement inutile. Je crois comprendre pourquoi les blocs de générateur lancent des exceptions à la réinitialisation sont en raison des préoccupations de tout état bâti. La nature même des blocs de groupes électrogènes les rend particulièrement illégales pour des opérations réinitialisées, mais cela ne signifie pas qu'un énumérateur réinitial est mauvais ou mal conçu. MOVENNET () CODE> Appel, un instantané de la source est pris. L'énumération complexe / projection / etc. est effectuée et des résultats obtenus. Nous souhaitons maintenant effectuer cette opération à nouveau, à partir du début. RESET () CODE> Fournit un mécanisme pour cette pile d'énumérateur entière pour réinitialiser l'état de départ sans avoir à reconstruire l'ensemble du graphique d'objet. En outre, il nous permet de conserver la construction du graphique d'objet séparé du consommateur qui doit exécuter cette énumération complexe plusieurs fois plusieurs fois. P> réinitialiser () code> est simplement transmis à l'instance d'énumérateur enveloppé, mais dans d'autres, un travail mineur est effectué, tel que la mise à jour d'une somme en cours, redémarre peut-être une heure de début. , ou reprogrammer l'instantané source de vos données. p> selectenumerator code> car il fonctionne le même rôle que énumérable.Sélectionnez code> p>
N'y a-t-il pas de résolution ?? :(
Je pense que cela n'existe que pour l'interopérabilité avec com. Le code normal .NET ne l'utilise pas et presque toutes les implémentations lancent une exception.