2008-08-07 38 views
11

Jestem prototypowanie niektórych filtrów kolekcji C# 3 i natknąłem się na to. Mam kolekcję produktów:Kiedy użyć metody rozszerzenia z lambda przez LINQtoObjects do filtrowania kolekcji?

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?" 
    } 
}; 

Teraz, jeśli mogę użyć LINQ do filtrowania to działa zgodnie z oczekiwaniami:

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

A jeśli używam Gdzie metodę rozszerzenia połączeniu z Lambda filtr działa jak dobrze:

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

Pytanie: Jaka jest różnica i dlaczego używać jednego nad drugim?

Odpowiedz

5

LINQ zamienia się w wywołania metod, takie jak kod, który masz.

Innymi słowy, nie powinno być żadnej różnicy.

Jednak w twoich dwóch fragmentach kodu nie wywołujesz .ToList w pierwszym, więc pierwszy fragment kodu wytworzy przeliczalne źródło danych, ale jeśli zadzwonisz .ToList na nim, oba powinny być takie same .

0

Poza różnicą tolist, # 2 jest o wiele bardziej czytelny i naturalne MOM

4

Jak wspomniano d będzie IEnumerable<MyProduct>, a f jest List<MyProduct>

Przekształcenie dokonuje C# kompilator

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

Konwertowane na (przed kompilacją do IL i z rozszerzonymi generycznymi):

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 

Należy pamiętać, że w tym prostym przypadku nie ma to większego znaczenia. Tam, gdzie Linq staje się naprawdę wartościowy, jest w dużo bardziej skomplikowanych pętlach.

Na przykład oświadczenie to może zawierać grupy-by, zamówienia i kilka zeznań letowych i nadal można je odczytać w formacie Linq, gdy odpowiednik .Method().Method.Method() może się skomplikować.

0

Składnia, której używasz dla d zostanie przekształcona przez kompilator w tę samą IL, co metody rozszerzeń. Składnia "podobna do SQL" ma być bardziej naturalnym sposobem reprezentowania wyrażenia LINQ (chociaż ja osobiście wolę metody rozszerzenia). Jak już wspomniano, pierwszy przykład zwróci wynik IEnumerable, podczas gdy drugi przykład zwróci wynik listy z powodu wywołania ToList(). Jeśli usuniesz wywołanie ToList() w drugim przykładzie, oba zwracają ten sam wynik, co Where, który zwraca wynik IEnumerable.