代码:
var list=GetList()
.where(x=>x.att01=="X")
.where(x=>x.att02=="Y")
.where(x=>x.att03=="Z")
.SingleOrDefault();
这真的等于
var list=GetList()
.where(x=>x.att01=="X" && x.att02=="Y" && x.att03=="Z")
.SingleOrDefault();
我用简单的数组测试了它,它显示它们是相同的。后者似乎做得更好。
答案 0 :(得分:4)
我用简单的数组测试了它,它显示它们是相同的。
从语义上讲,他们都是这样做的。 在这种特殊情况下(正在使用当前的重载),在幕后,WhereEnumerableIterator<TSource>
将输出带有链式谓词的单个枚举器:
public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source,
Func<TSource, bool> predicate)
{
// This is the important line
if (source is Iterator<TSource>)
return ((Iterator<TSource>)source).Where(predicate);
if (source is TSource[])
return new WhereArrayIterator<TSource>((TSource[])source, predicate);
if (source is List<TSource>)
return new WhereListIterator<TSource>((List<TSource>)source, predicate);
return new WhereEnumerableIterator<TSource>(source, predicate);
}
IEnumerable<TSource>
实际上是WhereEnumerableIterator<TSource>
来自Where
来电的public override IEnumerable<TSource> Where(Func<TSource, bool> predicate)
{
return new WhereEnumerableIterator<TSource>(source,
CombinePredicates(this.predicate,
predicate));
}
static Func<TSource, bool> CombinePredicates<TSource>(Func<TSource, bool> predicate1,
Func<TSource, bool> predicate2)
{
return x => predicate1(x) && predicate2(x);
}
。最终,它最终会合并谓词:
SingleOrDefault
但是,Func<TSource, bool>
本身有一个过载需要Where
,这样就不需要调用var list = GetList().SingleOrDefault(x => x.att01 == "X" &&
x.att02 == "Y" &&
x.att03 == "z");
了:
{{1}}
答案 1 :(得分:4)
鉴于&#34;标准&#34; Enumerable.Where
它们完全等效(从结果的角度来看)。第一个将由私人类WhereEnumerableIterator<TSource>
转换为第二个,确切地说是通过这种方法:
public override IEnumerable<TSource> Where(Func<TSource, bool> predicate) {
return new WhereEnumerableIterator<TSource>(source, CombinePredicates(this.predicate, predicate));
}
将以这种方式组合谓词:
static Func<TSource, bool> CombinePredicates<TSource>(Func<TSource, bool> predicate1, Func<TSource, bool> predicate2) {
return x => predicate1(x) && predicate2(x);
}
请参阅x => predicate1(x) && predicate2(x)
?
从技术上讲,第二个会更快一些,因为第一个会有更多的委托调用,但除非你过滤了数百万行,否则时差可以忽略不计。
请注意,虽然Enumerable.Where
做了有趣的技巧,但即使是非智能.Where
,例如:
public static class SimpleEnumerable
{
public static IEnumerable<TSource> SimpleWhere<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
{
foreach (TSource element in source)
{
if (predicate(element))
{
yield return element;
}
}
}
}
完全相同(但更慢!)。请参阅此处的示例:https://ideone.com/QAQZ65