Pourquoi un foreach code> une boucle en lecture seule? Quelles raisons sont là pour cela? P>
6 Réponses :
Je ne sais pas exactement ce que vous entendez par une "boucle réadonn", mais je suppose que vous voulez savoir pourquoi cela ne compile pas: Le code ci-dessus sera Donnez l'erreur de compilation suivante: P>
Cannot assign to 'x' because it is a 'foreach iteration variable'
+1. Il est similaire à dire foo x = nouveau foo (); Foo y = x; y = nouveau foo (); code> paramètre y code> à nouveau foo () code> ne fait rien à x code>. De même, avoir FOO code> comme variable de boucle et disant foo = nouveau foo (); code> (si vous pouviez **) ne fait rien au foo code> dans la collection.
C'est (la partie de copie) non true pour le type de référence, alors x déterrerait une référence à l'objet dans l'iNeuble
@Rune FS: Dans le cas des types de référence, c'est une copie i> de la référence. Même dans ce cas, cela ne ferait probablement pas ce que vous vouliez si vous pouviez vous assigner.
@Rune, x code> contiendrait l'adresse de l'objet. Dire x = nouvelle barre () code> créerait une nouvelle barre code> ou stocker son adresse dans x code>. L'objet dans la collection ne serait pas modifié. Ce n'est pas différent de transmettre un paramètre dans une fonction, puis de modifier le paramètre. La variable sur le site d'appel n'est pas affectée (sauf si un modificateur de code code> ou ref code> est utilisé dans la signature de la méthode).
@mark Je suis avec vous sur vous n'abandonnez pas à la "X", mais cela fait beaucoup de différence lorsque vous affectez une propriété / un champ de 'x' s'il s'agit d'un type de valeur ou d'un type de référence. Dans le premier cas, le changement est perdu lorsque la boucle se termine dans la seconde, elle durer jusqu'à modification à nouveau ou que l'objet est collecté.
@Anthony, il semble que vous avez mal compris moi et que c'est une référence à l'objet que la variable détient cette pourrait être mise en œuvre comme un pointeur, mais qui n'est pas requis par les spécifications
@Rune FS: Exactement, c'est l'idée qui m'a fait poser cette question
Je suppose que c'est comment l'itérateur se déplace dans la liste.
Dites que vous avez une liste triée: p> au milieu de p> foreach(var s in States)
{
}
Le contrat de Microsoft pour iEnumerable dit qu'un iEnumerable ne devrait fournir aucun moyen de mettre à jour la collection sans que l'exception soit lancée lors de l'énumération de l'élément suivant. Si j'avais mes druthers, un énumérateur de votre scénario serait libre d'inclure ou non d'inclure le Mississippi, mais il serait nécessaire d'énumérer exactement une fois tous les éléments existants tout au-delà de l'énumération, ou lancez une exception s'il ne pouvait pas faire cela.
Si, par ceci, vous voulez dire:
Pourquoi ne devrais-je pas modifier la collection qui est en train d'être
foreach code> d sur? p> blockQuote>Il n'y a pas de caution que les éléments que vous obtenez sortent dans une commande donnée et que l'ajout d'un article ou que la suppression d'un article ne provoque pas l'ordre des éléments de la collection de modifier ou Même l'énumérateur à devenir invalide. P>
Imaginez si vous avez exécuté le code suivant: p>
xxx pré> dès que vous avez frappé la boucle où je suis 6 (c.-à-d. Une fois que l'article est supprimé) tout pourrait arriver em>. L'énumérateur a peut-être été invalidée en raison de la suppression d'un article, tout aurait peut-être «mélanger par un» dans la collection sous-jacente provoquant un élément de prendre la place du retiré, ce qui signifie que vous «sautez». P> < p> Si vous vouliez dire "Pourquoi ne pouvez-je pas changer em> la valeur fournie sur chaque itération" alors, si la collecte que vous utilisez contient Types de valeur , les modifications que vous apportez ne seront pas conservées car c'est une valeur que vous «Nécessez-vous avec, plutôt que de référence em>. p> p>
Les problèmes naissent si vous ajoutez ou supprimez des éléments dans un autre thread tout en itérant: Selon l'endroit où vous êtes, vous risquez de manquer un élément ou d'appliquer votre code à un article supplémentaire. Ceci est détecté par le temps d'exécution (dans certains cas ou tout ???) et jette une exception: p> foreach code> fonctionne avec tout ce qui implémente l'interface code> iEnumerable code>. Afin d'éviter les problèmes de synchronisation, l'énumérable ne doit jamais être modifié tout en itération de celui-ci. foreach code> essaie d'obtenir un élément suivant chaque itération qui peut causer des problèmes si vous la modifiez d'un autre fil en même temps. P> p>
La commande Comme l'interface définit uniquement les méthodes minimales nécessaires pour lire le collecteur dans une direction, l'interface peut être mise en œuvre par une large gamme de collections. P>
Comme vous n'accumulez qu'un seul élément à la fois, toute la collection n'a pas à exister en même temps. Ceci est par exemple utilisé par les expressions LINQ, où cela crée le résultat à la volée lorsque vous le lisez, au lieu de créer d'abord tout le résultat, puis de vous laisser boucler. P> foreach code> utilise l'interface code> iEnumerable code> sur la boucle de la collection. L'interface uniquement définie des méthodes définies pour passer à travers une collection et obtenir l'élément actuel, il n'y a pas de méthodes de mise à jour de la collection. P>
Je ne sais pas ce que vous entendez avec lecture seule, mais je suppose que la compréhension de ce que la boucle de foresach est sous la hotte aidera. C'est le sucre syntaxique et pourrait également être écrit quelque chose comme ceci: si vous changez de la collection (liste), il est difficile de comprendre la manière de déterminer comment traiter l'itération.
L'attribution à l'élément (dans la version foreach) pourrait être visualisée comme étant d'essayer d'attribuer à Enumerator.Current, qui est en lecture seule ou en essayant de modifier la valeur de la locale détenant une référence à Enumerator.current auquel cas vous pourriez aussi bien introduire un Local vous-même parce que cela n'a plus rien à voir avec la liste énumérée. p> p>
Je ne suis pas sûr de ce que vous entendez par une boucle réadonnée. Faites-vous référence au fait que vous ne devez pas modifier la variable d'itération de la boucle? I.e pour chaque article dans myITEMS item.property = quelque chose suivant
Je ne sais pas comment appliquer le concept en lecture seule à une boucle. Ou voulez-vous dire pourquoi ils disent que c'est en lecture seule?
Si vous parlez de l'énumération - oui! Vous ne pouvez pas changer l'énumération que vous bouclez.
oui @tommy c'est ce que je voulais dire
Dupliquer de Stackoverflow.com/Questtions/776430/...
Question en double: Stackoverflow.com/Questtions/3549750/...