Hace algún tiempo leí que foreach funciona con "copias" de objetos y, por lo tanto, puede utilizarse para recuperar información en lugar de su actualización. No lo entiendo, ya que es completamente posible recorrer la lista de clases y cambiar su campo. ¡Gracias!C# Diferencia entre Foreach y para (no rendimiento)
Respuesta
Lo que puede ha leído es que no se puede modificar una colección al iterar sobre ella usando foreach
mientras que usted puede (si usted tiene cuidado) usando un bucle for
. Por ejemplo:
using System;
using System.Collections.Generic;
class Test
{
static void Main()
{
var list = new List<int> { 1, 4, 5, 6, 9, 10 };
/* This version fails with an InvalidOperationException
foreach (int x in list)
{
if (x < 5)
{
list.Add(100);
}
Console.WriteLine(x);
}
*/
// This version is okay
for (int i = 0; i < list.Count; i++)
{
int x = list[i];
if (x < 5)
{
list.Add(100);
}
Console.WriteLine(x);
}
}
}
Si eso es no lo que se está refiriendo a, por favor dar más detalles - que es difícil de explicar lo que ha leído sin saber exactamente lo que dijo.
No se puede modificar el elemento en un foreach
:
var list = new List<string>();
list.AddRange(new string[] { "A", "B", "C" });
foreach (var i in list)
{
// compilation error: Cannot assign 'i' because it is a 'foreach iteration variable'
i = "X";
}
Aunque cuando se trabaja con for
que está accediendo al elemento en la lista con su índice, y no el iterador, por lo que de esta manera se puede modificar la colección .
En realidad, puedes modificar los elementos (si pueden modificado) que son tipos de referencia. No puede reemplazarlos, agregarlos ni eliminarlos. La razón por la que su código no funcionará es porque una cadena es inmutable. Una vez creada, una cadena no se puede modificar de ninguna manera. parece ser una modificación en realidad es un reemplazo de una cadena por otra. Por lo tanto, en la ilustración que proporcionó arriba reemplaza uno de los elementos (o elimina uno y agrega uno) y no está permitido al enumerar una colección. – Kirk
foreach usa un iterador para obtener cada elemento de una secuencia. La secuencia puede ser Cualquier cosa que implemente IEnumerable. El IEnumerable no necesita ser finito (la secuencia 0 1 2 3 4 ... 1000 ...) es IEnumerable.
para es sólo una C# construcciones que le permiten declarar un bucle (utilizado para hacer todo tipo de cosas, no sólo iteración a través de colecciones)
Vale la pena señalar que la aplicación de iteración de .NET para las colecciones hace no es compatible con la modificación de secuencia durante la iteración.
foreach
está utilizando IEnumerable
para recorrer la colección. Esto hace que sea imposible modificar esta colección (eliminar, agregar elementos), pero aún puede modificar objetos dentro, si son tipos de referencia.
for
es una combinación simple de bucle simple combinado con acceso directo a los elementos en la colección. No hay ningún tipo de bloqueo mientras este ciclo está en marcha.
compararlo con un campo de sólo lectura:
private readonly List<int> MyList = new List<int>();
Ahora, en este código no puedo hacer MyList = new List<int>()
como que alterar lo MyList
puntos a, pero puede alterar la lista señaló con MyList.Add(3)
.
Del mismo modo, no se puede alterar la variable utilizada por el foreach
iteración, pero puedo lo que se refiere a:
foreach(List<int> lst in MyListOfLists)
{
lst = new List<int>(); // not allowed
lst.Add(3); // allowed
}
Por último, el empadronador utilizado para implementar foreach
no está obligado a seguir siendo válido si la colección subyacente es que se utiliza:
foreach(int x in SomeEnumerable)
{
if(x != 0)
SomeEnumerable.Add(0);
}
Suponiendo que Add
modifica SomeEnumerable
entonces el trabajo por encima de fuerza , es podría "trabajar" de una manera extraña y difícil de entender y podría lanzar una excepción. No se garantiza ningún comportamiento con dicho código y la modificación de una colección durante la enumeración se considera incorrecta por este motivo.
- 1. Diferencia entre rendimiento en Python y rendimiento en C#
- 2. ¿Rendimiento o diferencia de estilo entre "si" y "si no"?
- 3. Diferencia de rendimiento entre IIf() y Si
- 4. Diferencia entre C: y C:/
- 5. Diferencia entre foreach y for bucles sobre una clase IEnumerable en C#
- 6. ¿Diferencia de rendimiento entre las compilaciones de VALA y AOT?
- 7. C# diferencia entre == y equals()
- 8. Diferencia de rendimiento entre gcc y g ++ para el programa C
- 9. punteros void: diferencia entre C y C++
- 10. rendimiento de linq foreach
- 11. Diferencia entre C++ administrado y C++
- 12. Diferencia de rendimiento para multiproceso y multiproceso
- 13. ¿Por qué la diferencia de rendimiento entre C# (bastante más lento) y Win32/C?
- 14. Diferencia de rendimiento entre Amazon EC2 y Linode
- 15. ¿Cuál es la diferencia de rendimiento entre HttpModule y Global.aspx?
- 16. Diferencia de rendimiento entre Innodb y Myisam en Mysql
- 17. ¿Cuál es la diferencia entre catch {} y catch {continue;} en un bucle foreach C#?
- 18. ¿Hay alguna diferencia (de rendimiento) entre Depurar y Liberar?
- 19. ¿Cuál es la diferencia entre C++ administrado y C#?
- 20. ¿Diferencia de rendimiento entre el iterador ++ y el iterador ++?
- 21. C++ puro para Android y su rendimiento
- 22. Diferencia entre Lista y IList
- 23. ¿Hay alguna diferencia de rendimiento entre myCollection.Where (...). FirstOrDefault() y myCollection.FirstOrDefault (...)
- 24. LINQ: Diferencia entre 'Seleccionar c' y 'Seleccionar nueva (c ...'
- 25. C# Diferencia entre First() y Find()
- 26. Diferencia entre ASP.Net, C# .Net y VB.Net?
- 27. Diferencia entre read() y fgets() en C
- 28. Diferencia entre byte y char en C
- 29. Diferencia entre escribir en el archivo atómicamente y no
- 30. Diferencia de rendimiento entre VARCHAR2 a NUMBER
Jon, gracias. Sí, lo leí y entiendo que no puedo eliminar un elemento de, por ejemplo, un arreglo si lo atraviesa. Pero creo que puedo modificar el contenido de cada elemento, ¿verdad? – Radusko
Otra advertencia es que foreach puede implementarse de manera muy diferente que el indexador utilizado por for(). En el caso de la colección SelectedItems de la lista, hace una GRAN diferencia en términos de rendimiento. – EricLaw
@Radusko: Sí, puede modificar los datos en el objeto al que se hace referencia ... aunque si se trata de un tipo de valor, igual tratará con una copia. (Afortunadamente, no tendrás que lidiar con tipos de valores mutables). –