Vin*_*nce 18 .net c# linq internals
我在Enumerable.Single方法中发现(大致)这个代码,同时用一些反编译器检查它:
foreach (TSource current in source)
{
if (predicate(current))
{
result = current;
num += 1L;
}
}
if (num > 1L)
{
throw Error.MoreThanOneMatch();
}
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,它会在投掷之前循环遍历所有项目.它为什么不打破num > 1?
同意,从性能方面来看,它会更好(编辑:如果我们期望有多个项目匹配我们的谓词,我们不应该这样做):
foreach (TSource current in source)
{
if (predicate(current))
{
result = current;
num += 1L;
if (num > 1L)
throw Error.MoreThanOneMatch();
}
}
if (num == 0L)
throw Error.NoMatch();
return local;
Run Code Online (Sandbox Code Playgroud)
看起来他们决定让结果分析更加清晰,并将其与枚举源分开。但后来我想知道为什么不使用简单的开关:
switch((int)num)
{
case 0: throw Error.NoMatch();
case 1: return local;
default:
throw Error.MoreThanOneMatch();
}
Run Code Online (Sandbox Code Playgroud)
关于性能问题 - 我认为假设当您真正期望单一结果Single时应该调用它。零个或多个结果是一条异常路径,不应经常发生(作为任何异常)。因此,如果源包含许多与谓词匹配的项目,则更多的是程序的逻辑错误。