何时使用lambda over LINQtoObjects的扩展方法来过滤集合?

问题描述:

我正在对一些C#3收集过滤器进行原型设计,并遇到此问题。 我的产品的集合:何时使用lambda over LINQtoObjects的扩展方法来过滤集合?

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

现在,如果我使用LINQ筛选它按预期工作:

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

如果我使用Where扩展方法用LAMBDA组合过滤器工作原理好:

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

问题:的区别是什么,以及为什么使用了另一种?

LINQ变成类似您所拥有的代码的方法调用。

换句话说,应该没有区别。

但是,在您的两段代码中,第一段不会调用.ToList,因此第一段代码将生成可枚举的数据源,但如果您对它调用.ToList,则两者应该是相同的。

除了ToList差,#2是一个很大的可读和自然IMO

如前所述d将是IEnumerable<MyProduct>而f是List<MyProduct>

的转换由C#编译器完成

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

转换为(在汇编到IL之前并且扩展了泛型):

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 

请注意,在这种简单的情况下,它几乎没有什么区别。 Linq变得非常有价值的地方在于更复杂的循环。

例如,如果等价的.Method().Method.Method()会变得复杂,此语句可能包含分组,by命令和一些let语句,并且仍然可以用Linq格式读取。

您正在使用的d的语法将被编译器转换为与扩展方法相同的IL。 “类似于SQL”的语法应该是一种更自然的方式来表示LINQ表达式(尽管我个人更喜欢扩展方法)。正如已经指出的那样,第一个示例将返回一个IEnumerable结果,而第二个示例将因ToList()的调用返回List结果。如果在第二个示例中删除ToList()调用,则它们将返回与Where返回IEnumerable结果相同的结果。