Quando utilizzare un metodo di estensione con lambda su LINQtoObjects per filtrare una raccolta?
Domanda
Sto prototipando alcuni filtri di raccolta C# 3 e mi sono imbattuto in questo.Ho una collezione di prodotti:
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?"
}
};
Ora se utilizzo LINQ per filtrare funziona come previsto:
var d = (from mp in MyProducts
where mp.Price < 50d
select mp);
E se utilizzo il metodo di estensione Where combinato con un Lambda, anche il filtro funziona:
var f = MyProducts.Where(mp => mp.Price < 50d).ToList();
Domanda: Qual è la differenza e perché usarne uno rispetto all'altro?
Soluzione
LINQ si trasforma in chiamate di metodo come il codice che hai.
In altre parole, non dovrebbe esserci alcuna differenza.
Tuttavia, nei tuoi due pezzi di codice non chiami .ToList nel primo, quindi il primo pezzo di codice produrrà un'origine dati enumerabile, ma se chiami .ToList su di esso, i due dovrebbero essere uguali.
Altri suggerimenti
Come accennato d sarà IEnumerable<MyProduct>
mentre f è List<MyProduct>
La conversione viene eseguita dal compilatore C#
var d =
from mp in MyProducts
where mp.Price < 50d
select mp;
Viene convertito in (prima della compilazione in IL e con i generici espansi):
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
Si noti che in questo caso semplice fa poca differenza.Il punto in cui Linq diventa davvero prezioso è in circuiti molto più complicati.
Ad esempio, questa istruzione potrebbe includere group-by, ordini e alcune istruzioni let ed essere comunque leggibile in formato Linq quando l'equivalente .Method().Method.Method()
diventerebbe complicato.
A parte la differenza ToList, il numero 2 è molto più leggibile e naturale IMO
La sintassi che stai utilizzando D verrà trasformato dal compilatore nello stesso IL dei metodi di estensione.La sintassi "simile a SQL" dovrebbe essere un modo più naturale per rappresentare un'espressione LINQ (anche se personalmente preferisco i metodi di estensione).Come già sottolineato, il primo esempio restituirà un risultato IEnumerable mentre il secondo esempio restituirà un risultato List a causa della chiamata a ToList().Se rimuovi la chiamata ToList() nel secondo esempio, entrambi restituiranno lo stesso risultato in cui Where restituisce un risultato IEnumerable.