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

时间:2008-08-07 19:23:13

标签: c# linq .net-3.5 lambda

我正在对一些C#3集合过滤器进行原型设计并遇到了这个问题。 我有一系列产品:

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();

问题:有什么区别,为什么要使用其中一个?

4 个答案:

答案 0 :(得分:5)

LINQ变成方法调用,就像你拥有的代码一样。

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

但是,在你的两段代码中你没有调用.ToList在第一段,所以第一段代码将产生一个可枚举的数据源,但是如果你在它上面调用.ToList,那么两者应该是相同的。

答案 1 :(得分:4)

如上所述,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变得非常有价值的地方是更复杂的循环。

例如,这个语句可能包括分组,命令和一些let语句,当等效的.Method().Method.Method()变得复杂时,仍然可以用Linq格式读取。

答案 2 :(得分:0)

除了ToList之外,#2更具可读性和自然性IMO

答案 3 :(得分:0)

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