我正在对一些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();
问题:有什么区别,为什么要使用其中一个?
答案 0 :(得分:5)
LINQ变成方法调用,就像你拥有的代码一样。
换句话说,应该没有区别。
但是,在你的两段代码中你没有调用.ToList在第一段,所以第一段代码将产生一个可枚举的数据源,但是如果你在它上面调用.ToList,那么两者应该是相同的。
答案 1 :(得分:4)
如上所述,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变得非常有价值的地方是更复杂的循环。
例如,这个语句可能包括分组,命令和一些let语句,当等效的.Method().Method.Method()
变得复杂时,仍然可以用Linq格式读取。
答案 2 :(得分:0)
除了ToList之外,#2更具可读性和自然性IMO
答案 3 :(得分:0)
您用于 d 的语法将由编译器转换为与扩展方法相同的IL。 “SQL-like”语法应该是表示LINQ表达式的更自然的方式(尽管我个人更喜欢扩展方法)。正如已经指出的那样,第一个示例将返回IEnumerable结果,而第二个示例将返回由于调用ToList()而导致的List结果。如果在第二个示例中删除了ToList()调用,它们将返回与Where返回IEnumerable结果相同的结果。