C# “双倍或三倍”;其中;Linq中的子句
代码: 这真的等于C# “双倍或三倍”;其中;Linq中的子句,c#,linq,C#,Linq,代码: 这真的等于 var list=GetList() .where(x=>x.att01=="X") .where(x=>x.att02=="Y") .where(x=>x.att03=="Z") .SingleOrDefault(); 我用简单的数组对它进行了测试,结果表明它们是一样的。后者似乎做得更好 我用简单的数组对它进行了测试,结果表明它们是一样的 从语义上讲,它们都做相同的事情。在这种特殊情况下(使用当前重载),在幕后,where
var list=GetList()
.where(x=>x.att01=="X")
.where(x=>x.att02=="Y")
.where(x=>x.att03=="Z")
.SingleOrDefault();
我用简单的数组对它进行了测试,结果表明它们是一样的。后者似乎做得更好
我用简单的数组对它进行了测试,结果表明它们是一样的
从语义上讲,它们都做相同的事情。在这种特殊情况下(使用当前重载),在幕后,whereEnumerableTerator
将输出一个带有链式谓词的枚举数:
var list=GetList()
.where(x=>x.att01=="X" && x.att02=="Y" && x.att03=="Z")
.SingleOrDefault();
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);
}
但是,SingleOrDefault
本身有一个重载,它接受一个Func
,这样就不需要调用,其中
:
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);
}
给定一个“标准”可枚举。其中
它们是完全等效的(从结果的角度)。第一个将由私有类转换为第二个,确切地说是通过此方法:
var list = GetList().SingleOrDefault(x => x.att01 == "X" &&
x.att02 == "Y" &&
x.att03 == "z");
完全相同(但更慢!)。参见此处的示例:相同。它被称为消除代码重复。把所有东西都放在一个条件下。第二种方法会更快,因为循环列表只有一次。@Fabio False。。。
可枚举。Where
执行一些技巧,并将多个。Where
自动压缩为单个。Where
。查找WhereEnumerableIterator
类。@卡斯滕我看不出副作用能改变什么。如果x.att01!=“x”
@Carsten你可以玩
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);
}
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;
}
}
}
}