2008-08-07 17 views
11

Estoy creando prototipos de algunos filtros de colección C# 3 y me encontré con esto. que tienen una colección de productos:Cuándo usar un método de extensión con lambda sobre LINQtoObjects para filtrar una colección?

public class MyProduct 
{ 
    public string Name { get; set; } 
    public Double Price { get; set; } 
    public string Description { get; set; } 
} 

var MyProducts = new List<MyProduct> 
{    
    new MyProduct 
    { 
     Name = "Surfboard", 
     Price = 144.99, 
     Description = "Most important thing you will ever own." 
    }, 
    new MyProduct 
    { 
     Name = "Leash", 
     Price = 29.28, 
     Description = "Keep important things close to you." 
    } 
    , 
    new MyProduct 
    { 
     Name = "Sun Screen", 
     Price = 15.88, 
     Description = "1000 SPF! Who Could ask for more?" 
    } 
}; 

Ahora si uso de LINQ para filtrar funciona como se esperaba:

var d = (from mp in MyProducts 
      where mp.Price < 50d 
      select mp); 

Y si uso el caso de método de extensión combinada con un Lambda el filtro funciona como así:

var f = MyProducts.Where(mp => mp.Price < 50d).ToList(); 

pregunta: ¿Cuál es la diferencia, y por qué usar uno sobre el otro?

Respuesta

5

LINQ se convierte en llamadas a métodos como el código que tiene.

En otras palabras, no debería haber ninguna diferencia.

Sin embargo, en sus dos códigos no está llamando .ToList en el primero, de modo que la primera parte del código generará una fuente de datos enumerable, pero si llama a .ToList, los dos deberían ser iguales .

0

Aparte de la diferencia ToList, # 2 es mucho más fácil de leer y natural OMI

4

Como se mencionó D será IEnumerable<MyProduct> mientras que f es List<MyProduct>

La conversión se realiza por el compilador de C#

var d = 
    from mp in MyProducts 
    where mp.Price < 50d 
    select mp; 

se convierte en (antes de la compilación de IL y con los genéricos expandido):

var d = 
    MyProducts. 
    Where<MyProduct>(mp => mp.Price < 50d). 
    Select<MyProduct>(mp => mp); 
    //note that this last select is optimised out if it makes no change 

Tenga en cuenta que en este caso simple tiene poca importancia. Donde Linq se vuelve realmente valioso es en circuitos mucho más complicados.

Por ejemplo, esta declaración podría incluir grupos por bys, pedidos y algunas declaraciones de let, y seguir siendo legible en formato Linq cuando el equivalente .Method().Method.Method() se complique.

0

La sintaxis que está utilizando para d se transformará por el compilador en la misma IL que los métodos de extensión. Se supone que la sintaxis "SQL-like" es una forma más natural de representar una expresión LINQ (aunque personalmente prefiero los métodos de extensión). Como ya se ha señalado, el primer ejemplo arrojará un resultado de IEnumerable, mientras que el segundo ejemplo arrojará un resultado de la Lista debido a la llamada a ToList(). Si elimina la llamada a Lista() en el segundo ejemplo, ambos devolverán el mismo resultado que Donde devuelve un resultado de IEnumerable.

Cuestiones relacionadas