2012-06-19 11 views
6

He estado experimentando con LINQ para ver lo que puede hacer - y yo realmente soy amante que hasta ahora :)LINQ ejecución diferida con los valores locales

escribí algunas consultas de un algoritmo, pero yo no' t obtener los resultados que yo esperaba ... la enumeración siempre devuelve vacío:

el caso # 1

List<some_object> next = new List<some_object>(); 
some_object current = null; 

var valid_next_links = 
    from candidate in next 
    where (current.toTime + TimeSpan.FromMinutes(5) <= candidate.fromTime) 
    orderby candidate.fromTime 
    select candidate; 

current = something; 
next = some_list_of_things; 

foreach (some_object l in valid_next_links) 
{ 
    //do stuff with l 
} 

he cambiado la declaración de consulta en línea a ser así, y funcionó bien:

el caso # 2

foreach (some_object l in 
     (from candidate in next 
     where (current.toTime + TimeSpan.FromMinutes(5) <= candidate.fromTime) 
     orderby candidate.fromTime 
     select candidate)) 
{ 
    //do stuff with l 
} 

¿Alguien sabe por qué no funciona en el caso # 1? De la forma en que lo entendí, la consulta no se evaluó cuando la declaró, por lo que no veo cómo hay diferencia.

Respuesta

7

Cambios en current serán capturados, pero la consulta ya se sabe el valor de next. Agregar elementos adicionales a la lista existente los hará aparecer en la consulta, pero cambiar el valor de la variable para hacer referencia a una lista diferente por completo no tendrá ningún efecto. Básicamente, si expande mentalmente la consulta de una expresión de consulta a una forma "normal", cualquier variable presente en una expresión lambda será capturada como una variable, pero cualquier variable presente directamente como argumento será evaluada inmediatamente. Eso solo capturará el valor de la variable , no los elementos presentes en la lista, pero aún significa que no se verá el cambio del valor de la variable en sí. Su primera consulta se expande a:

var valid_next_links = next 
     .Where(candidate => (current.toTime + TimeSpan.FromMinutes(5) <= candidate.fromTime)) 
     .OrderBy(candidate => candidate.fromTime); 
Cuestiones relacionadas