我正在对一些 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();

问题: 有什么区别,为什么要使用其中一种而不是另一种?

有帮助吗?

解决方案

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

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

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

其他提示

如前所述 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 真正有价值的地方是在更复杂的循环中。

例如,此语句可以包含 group-by、orders 和一些 let 语句,并且在等效的情况下仍然可以以 Linq 格式读取 .Method().Method.Method() 会变得复杂。

除了 ToList 差异之外,#2 在我看来更具可读性和自然性

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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top