何时使用lambda over LINQtoObjects的扩展方法来过滤集合?
问题描述:
我正在对一些C#3收集过滤器进行原型设计,并遇到此问题。 我的产品的集合:何时使用lambda over LINQtoObjects的扩展方法来过滤集合?
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是一个很大的可读和自然IMO
答
如前所述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变得非常有价值的地方在于更复杂的循环。
例如,如果等价的.Method().Method.Method()
会变得复杂,此语句可能包含分组,by命令和一些let语句,并且仍然可以用Linq格式读取。
答
您正在使用的d的语法将被编译器转换为与扩展方法相同的IL。 “类似于SQL”的语法应该是一种更自然的方式来表示LINQ表达式(尽管我个人更喜欢扩展方法)。正如已经指出的那样,第一个示例将返回一个IEnumerable结果,而第二个示例将因ToList()的调用返回List结果。如果在第二个示例中删除ToList()调用,则它们将返回与Where返回IEnumerable结果相同的结果。