何时使用 LINQtoObjects 上的 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();
问题: 有什么区别,为什么要使用其中一种而不是另一种?
解决方案
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 结果相同的结果。
不隶属于 StackOverflow