何时在LINQtoObjects上对lambda使用扩展方法来过滤集合?
时间:2020-03-05 18:38:27 来源:igfitidea点击:
我正在制作一些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是更易读和更自然的IMO
回答
如前所述,d将是IEnumerable <MyProduct>
,而f是List <MyProduct>
。
转换由Ccompiler完成
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()变得复杂时,该语句可能包含分组依据,订单和一些let语句,并且仍然可以Linq格式读取。
回答
用于d的语法将被编译器转换为与扩展方法相同的IL。 " SQL式"语法被认为是表示LINQ表达式的更自然的方式(尽管我个人更喜欢扩展方法)。正如已经指出的,由于调用ToList(),第一个示例将返回IEnumerable结果,而第二个示例将返回List结果。如果在第二个示例中删除ToList()调用,它们将都返回与Where返回IEnumerable结果相同的结果。