2008-08-07 16 views
11

Je suis en train de prototyper des filtres de collection C# 3 et je suis tombé dessus. J'ai une collection de produits:Quand utiliser une méthode d'extension avec lambda sur LINQtoObjects pour filtrer une collection?

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 Where d'extension combinée avec un Lambda le filtre fonctionne comme bien:

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

question: Quelle est la différence, et pourquoi utiliser un sur l'autre?

Répondre

5

LINQ se transforme en appels de méthode comme le code que vous avez.

En d'autres termes, il ne devrait pas y avoir de 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, les deux devraient être les mêmes .

0

Autre que la différence de ToList, # 2 est beaucoup plus lisible et naturel OMI

4

Comme mentionné d sera IEnumerable<MyProduct> alors 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 IL et génériques): expansion

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. Où Linq devient vraiment précieux est dans des boucles beaucoup plus compliquées. Par exemple, cette instruction pourrait inclure des commandes groupées, des ordres et quelques instructions let, et être toujours lisible au format Linq lorsque l'équivalent .Method().Method.Method() se compliquerait.

0

La syntaxe que vous utilisez pour d sera transformée par le compilateur dans la même IL que les méthodes d'extension. La syntaxe "SQL-like" est supposée être une façon plus naturelle de représenter une expression LINQ (bien que personnellement je préfère les méthodes d'extension). Comme cela a déjà été souligné, le premier exemple retournera un résultat IEnumerable alors que le deuxième exemple retournera un résultat List dû à l'appel de ToList(). Si vous supprimez l'appel ToList() dans le second exemple, ils renverront le même résultat que Where renvoie un résultat IEnumerable.

Questions connexes