Cierre y Linq
IEnumerable
string vowels = “aeiou”;
for (int i = 0; i < vowels.Length; i++)
charQuery1 = charQuery1.Where(c => c != vowels[i]);
foreach (char c in charQuery1) Console.Write(c);
Esto lanzará una excepción IndexOutOfRangeException. El compilador delimita la variable “i” del bucle for como si se hubiera declarado fuera. ¿Alguien puede analizar esto y ayudarme a entenderlo mejor? La depuración no me ayudó mucho en este caso. Estoy tratando de entender el papel del compilador aquí.
davy.ai
En este fragmento de código, se inicializa un
IEnumerable<char>
charQuery1
con la cadena de texto “Not what you might expect”. Luego se define una cadena de textovowels
como “aeiou”.A continuación, el código entra en un bucle
for
que iterará sobre los índices de la cadena de textovowels
. En cada iteración, se pasa una expresión lambda al método de extensiónWhere
decharQuery1
.La expresión lambda define una variable
c
que representa el carácter actual encharQuery1
. La lambda luego verifica sic
es diferente devowels[i]
, dondei
es el índice actual de la cadena de textovowels
.Sin embargo, el problema con este código es el hecho de que la expresión lambda captura la variable de bucle
i
. La expresión lambda no se ejecuta de inmediato, sino que se guarda para su ejecución posterior. Cuando la lambda se ejecuta más adelante, utilizará el valor dei
tal como existe en ese momento, en lugar del valor dei
en el momento en que se definió la expresión lambda.Esto significa que cuando se ejecuta la lambda, siempre utilizará el último valor de
i
del bucle, que es5
(el índice de la letra “u” en “vowels”). Esto resulta en que la lambda filtra solo los caracteres “u” encharQuery1
, en lugar de todas las vocales.Para solucionar este problema, puedes definir una variable local dentro del bucle y asignarle el valor de
i
. Esto crea una nueva variable que tiene un ámbito en cada iteración del bucle y que la lambda puede capturar correctamente:Este código imprimirá
"Nt wht y mght xpct"
, que elimina todas las vocales de la cadena original según se pretendía.