Quando usar um método de extensão com lambda sobre LINQtoObjects para filtrar uma coleção?
Pergunta
Eu sou de prototipagem alguns C# 3 coleção de filtros e me deparei com este.Eu tenho uma coleção de produtos:
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?"
}
};
Agora, se eu usar o LINQ para filtrar ele funciona como esperado:
var d = (from mp in MyProducts
where mp.Price < 50d
select mp);
E se eu usar o método Where combinado com um Lambda, o filtro funciona assim:
var f = MyProducts.Where(mp => mp.Price < 50d).ToList();
Pergunta: Qual é a diferença, e por que usar um sobre o outro?
Solução
LINQ se transforma em chamadas de método como o código que você tem.
Em outras palavras, não deve haver nenhuma diferença.
No entanto, em suas duas partes de código que não estão ligando .ToList no primeiro, de modo que a primeira parte do código que irá produzir um enumerable fonte de dados, mas se você chamar .ToList sobre ela, os dois devem ser os mesmos.
Outras dicas
Como mencionado d IEnumerable<MyProduct>
enquanto f é List<MyProduct>
A conversão é feita pelo compilador C#
var d =
from mp in MyProducts
where mp.Price < 50d
select mp;
É convertido para (antes de compilação para IL e com 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
Observe que, neste caso simples, pouca diferença faz.Onde Linq torna-se muito importante, é muito mais complicado loops.
Por exemplo, esta declaração poderia incluir o grupo a prazo, encomendas e alguns deixe declarações e, ainda, ser legível em Linq formato quando o equivalente .Method().Method.Method()
iria ficar complicado.
Diferente do ToList diferença, #2 é muito mais legível e natural IMO
A sintaxe que você estiver usando para d vai ter transformado pelo compilador para a mesma IL como os métodos de extensão.O "SQL-like" sintaxe é suposto ser uma maneira mais natural de representar uma expressão do LINQ (embora eu, pessoalmente, prefiro os métodos de extensão).Como já foi apontado, o primeiro exemplo vai retornar um IEnumerable resultado, enquanto o segundo exemplo retorna uma Lista de resultados devido à chamada para ToList().Se você remover o ToList() na chamada segunda exemplo, eles retornam o mesmo resultado, Onde retorna um IEnumerable resultado.