es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Cierre y Linq

IEnumerable charQuery1 = “No es lo que esperarías”;
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í.

Tags:  , ,

Answer

  1. Avatar for 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 texto vowels como “aeiou”.

    A continuación, el código entra en un bucle for que iterará sobre los índices de la cadena de texto vowels. En cada iteración, se pasa una expresión lambda al método de extensión Where de charQuery1.

    La expresión lambda define una variable c que representa el carácter actual en charQuery1. La lambda luego verifica si c es diferente de vowels[i], donde i es el índice actual de la cadena de texto vowels.

    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 de i tal como existe en ese momento, en lugar del valor de i 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 es 5 (el índice de la letra “u” en “vowels”). Esto resulta en que la lambda filtra solo los caracteres “u” en charQuery1, 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:

    IEnumerable<char> charQuery1 = "Not what you might expect";
    string vowels = "aeiou";
    for (int i = 0; i < vowels.Length; i++)
    {
       int index = i; // definir una variable local para capturar el índice
       charQuery1 = charQuery1.Where(c => c != vowels[index]);
    }
    foreach (char c in charQuery1) Console.Write(c);
    

    Este código imprimirá "Nt wht y mght xpct", que elimina todas las vocales de la cadena original según se pretendía.

Comments are closed.