Quand utiliser une méthode d'extension avec lambda sur LINQtoObjects pour filtrer une collection ?
Question
Je suis en train de prototyper des filtres de collection C# 3 et je suis tombé sur cela.J'ai une collection de produits :
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?"
}
};
Maintenant, si j'utilise LINQ pour filtrer, cela fonctionne comme prévu :
var d = (from mp in MyProducts
where mp.Price < 50d
select mp);
Et si j'utilise la méthode d'extension Where combinée à un Lambda, le filtre fonctionne également :
var f = MyProducts.Where(mp => mp.Price < 50d).ToList();
Question: Quelle est la différence et pourquoi utiliser l’un plutôt que l’autre ?
La solution
LINQ se transforme en appels de méthode comme le code que vous avez.
En d’autres termes, il ne devrait y avoir aucune différence.
Cependant, dans vos deux morceaux de code, vous n'appelez pas .ToList dans le premier, donc le premier morceau de code produira une source de données énumérable, mais si vous appelez .ToList dessus, les deux devraient être identiques.
Autres conseils
Comme mentionné, d sera IEnumerable<MyProduct>
tandis que f est List<MyProduct>
La conversion est effectuée par le compilateur C#
var d =
from mp in MyProducts
where mp.Price < 50d
select mp;
Est converti en (avant compilation en IL et avec les génériques étendus) :
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
Notez que dans ce cas simple, cela fait peu de différence.Là où Linq devient vraiment utile, c'est dans des boucles beaucoup plus compliquées.
Par exemple, cette instruction pourrait inclure des group-bys, des commandes et quelques instructions let tout en restant lisible au format Linq lorsque l'équivalent .Method().Method.Method()
ça deviendrait compliqué.
Outre la différence ToList, le numéro 2 est beaucoup plus lisible et naturel, selon mon humble avis.
La syntaxe que vous utilisez pour d sera transformé par le compilateur dans le même IL que les méthodes d'extension.La syntaxe "de type SQL" est censée être un moyen plus naturel de représenter une expression LINQ (même si je préfère personnellement les méthodes d'extension).Comme cela a déjà été souligné, le premier exemple renverra un résultat IEnumerable tandis que le deuxième exemple renverra un résultat List en raison de l'appel à ToList().Si vous supprimez l'appel ToList() dans le deuxième exemple, ils renverront tous deux le même résultat que Where renvoie un résultat IEnumerable.