¿Cuándo utilizar un método de extensión con lambda sobre LINQtoObjects para filtrar una colección?

StackOverflow https://stackoverflow.com/questions/5194

  •  08-06-2019
  •  | 
  •  

Pregunta

Estoy creando un prototipo de algunos filtros de colección de C# 3 y me encontré con esto.Tengo una colección de productos:

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 LINQ para filtrar, funciona como se esperaba:

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

Y si uso el método de extensión Where combinado con Lambda, el filtro también funciona:

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

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

¿Fue útil?

Solución

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

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

Sin embargo, en sus dos fragmentos de código no está llamando a .ToList en el primero, por lo que el primer fragmento de código producirá una fuente de datos enumerable, pero si llama a .ToList en él, los dos deberían ser iguales.

Otros consejos

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

La conversión la realiza el compilador de C#.

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

Se convierte a (antes de la compilación a IL y con los genéricos expandidos):

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 sencillo hay poca diferencia.Donde Linq se vuelve realmente valioso es en bucles mucho más complicados.

Por ejemplo, esta declaración podría incluir grupos, órdenes y algunas declaraciones let y aún ser legible en formato Linq cuando el equivalente .Method().Method.Method() se complicaría.

Aparte de la diferencia de ToList, el número 2 es mucho más legible y natural en mi opinión.

La sintaxis que estás usando para d El compilador lo transformará en el mismo IL que los métodos de extensión.Se supone que la sintaxis "similar a SQL" 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 devolverá un resultado IEnumerable mientras que el segundo ejemplo devolverá un resultado de Lista debido a la llamada a ToList().Si elimina la llamada ToList() en el segundo ejemplo, ambas devolverán el mismo resultado que Where devuelve un resultado IEnumerable.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top