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

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

public class MyProduct
{
    public string Name { get; set; }
    public Double Price { get; set; }
    public string Description { get; set; }
}

var MyProducts = new  List
{            
    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);

如果我使用与Lambda结合的Where扩展方法,则过滤器也可以工作:

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

Question: What is the difference, and why use one over the other?

0

4 答案

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

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

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

0
额外

除ToList以外,#2更具可读性和自然的IMO特性

0
额外

As mentioned d will be IEnumerable while f is List

转换由C#编译器完成

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

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

var d = 
    MyProducts.
    Where( mp => mp.Price < 50d ).
    Select( mp => mp ); 
    //note that this last select is optimised out if it makes no change

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

例如,当等效的 .Method()。Method.Method()会变得复杂时,这个语句可能包含group bys,orders和一些let语句,并且仍然可以用Linq格式读取。

0
额外

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

0
额外