Tengo una consulta linq, cuyos resultados repito en un ciclo foreach.consulta foreach y linq - necesito ayuda para tratar de entender, por favor
La primera es una pregunta que agarra una colección de controles de un panel de diseño mesa, a continuación, iterar sobre la colección y quitar los controles de la TableLayoutPanel así:
var AllItems = (from Item in this.tableLayoutPanel1.Controls.OfType<ItemControl>()
select Item);
foreach (ItemControl item in AllItems)
{
Trace.WriteLine("Removing " + item.ToString());
this.tableLayoutPanel1.Controls.Remove(item);
item.Dispose();
}
Lo anterior no hacer lo que yo esperado (es decir, lanzar un error), elimina solo la mitad de los controles (los ODD numerados) parece que en cada iteración AllItems reduce a sí mismo, y aunque la colección subyacente se está modificando no se produce ningún error.
Si yo mismo tipo con una matriz de cadenas:
string[] strs = { "d", "c", "A", "b" };
List<string> stringList = strs.ToList();
var allitems = from letter in stringList
select letter;
foreach (string let in allitems)
{
stringList.Remove(let);
}
Esta vez Visual Studio genera un error (como se esperaba) quejándose de que la colección subyacente ha cambiado.
¿Por qué el primer ejemplo tampoco explota?
Hay algo sobre Iterators/IEnumerable que no estoy entendiendo aquí y me pregunto si alguien podría ayudarme a entender lo que está pasando bajo el capó con linq y foreach.
(Soy consciente de que puedo curar estas dos cuestiones para AllItems.ToList(); antes de iterar, pero me gustaría entender por qué el segundo ejemplo se emite un error y el primero no lo hace)
es la razón para este problema no está relacionado con el hecho de que 'Enumerable.OfType' se implementa mediante el uso de ejecución diferida, por lo tanto, la secuencia que siempre cambian en cada enumeración? –
@TimSchmelter Bueno, 'OfType' simplemente se enumera mediante el uso del enumerador de origen directamente - mientras no se está haciendo la comprobación, lo mismo sucedería si se enumeran los objetos, y poner la verificación dentro del bucle. El enumerador subyacente no está realizando una comprobación de si la colección de control se ha modificado. –
@TimSchmelter: sospecho que todas las operaciones LINQ podrían eliminarse del código postal original, y se comportaría exactamente de la misma manera. Como dice Reed, este es el resultado de la implementación del enumerador. OfType no tiene nada que ver con eso. – StriplingWarrior