C# 何时在 LINQtoObjects 上使用带有 lambda 的扩展方法来过滤集合?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5194/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
When to use an extension method with lambda over LINQtoObjects to filter a collection?
提问by KP.
I am prototyping some C# 3 collection filters and came across this. I have a collection of products:
我正在制作一些 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?"
}
};
Now if I use LINQ to filter it works as expected:
现在,如果我使用 LINQ 进行过滤,它会按预期工作:
var d = (from mp in MyProducts
where mp.Price < 50d
select mp);
And if I use the Where extension method combined with a Lambda the filter works as well:
如果我将 Where 扩展方法与 Lambda 结合使用,过滤器也能正常工作:
var f = MyProducts.Where(mp => mp.Price < 50d).ToList();
Question:What is the difference, and why use one over the other?
问题:有什么区别,为什么要使用一个?
采纳答案by Lasse V. Karlsen
LINQ turns into method calls like the code you have.
LINQ 会像您拥有的代码一样转换为方法调用。
In other words, there should be no difference.
换句话说,应该没有区别。
However, in your two pieces of code you are not calling .ToList in the first, so the first piece of code will produce an enumerable data source, but if you call .ToList on it, the two should be the same.
但是,在您的两段代码中,您没有在第一段中调用 .ToList ,因此第一段代码将生成一个可枚举的数据源,但是如果您对其调用 .ToList ,则两者应该相同。
回答by Ricky
Other than the ToList difference, #2 is a lot more readable and natural IMO
除了 ToList 不同之外,#2 更具可读性和自然 IMO
回答by Keith
As mentioned d will be IEnumerable<MyProduct>
while f is List<MyProduct>
如前所述 d 将是IEnumerable<MyProduct>
而 f 是List<MyProduct>
The conversion is done by the C# compiler
转换由 C# 编译器完成
var d =
from mp in MyProducts
where mp.Price < 50d
select mp;
Is converted to (before compilation to IL and with generics expanded):
转换为(在编译为 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
Note that in this simple case it makes little difference. Where Linq becomes really valuable is in much more complicated loops.
请注意,在这个简单的情况下,它几乎没有区别。Linq 真正有价值的地方在于更复杂的循环。
For instance this statement could include group-bys, orders and a few let statements and still be readable in Linq format when the equivalent .Method().Method.Method()
would get complicated.
例如,此语句可以包含分组依据、订单和一些 let 语句,并且当等效项.Method().Method.Method()
变得复杂时,仍然可以以 Linq 格式阅读。
回答by Scott Dorman
The syntax you are using for dwill get transformed by the compiler into the same IL as the extension methods. The "SQL-like" syntax is supposed to be a more natural way to represent a LINQ expression (although I personally prefer the extension methods). As has already been pointed out, the first example will return an IEnumerable result while the second example will return a List result due to the call to ToList(). If you remove the ToList() call in the second example, they will both return the same result as Where returns an IEnumerable result.
您用于d的语法将被编译器转换为与扩展方法相同的 IL。“类 SQL”语法应该是一种更自然的表示 LINQ 表达式的方式(尽管我个人更喜欢扩展方法)。正如已经指出的那样,第一个示例将返回一个 IEnumerable 结果,而第二个示例将由于调用 ToList() 而返回一个 List 结果。如果删除第二个示例中的 ToList() 调用,它们将返回与 Where 返回 IEnumerable 结果相同的结果。