C# 何时使用LINQtoObjects上的lambda扩展方法筛选集合?

C# 何时使用LINQtoObjects上的lambda扩展方法筛选集合?,c#,linq,.net-3.5,lambda,C#,Linq,.net 3.5,Lambda,我是原型一些C3收集过滤器,并遇到了这一点。 我有一系列产品: public class MyProduct { public string Name { get; set; } public Double Price { get; set; } public string Description { get; set; } } var MyProducts = new List<MyProduct> { new MyPr

我是原型一些C3收集过滤器,并遇到了这一点。 我有一系列产品:

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更具可读性和自然性,正如前面提到的,d将是IEnumerable,而f是List

转换由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真正有价值的地方是在更复杂的循环中


例如,此语句可能包括group by、orders和一些let语句,并且当等效的.Method.Method.Method变得复杂时,仍然可以以Linq格式读取。

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