我正在查看由Linq 扩展方法ElementAt的.NET Reflector生成的一些代码,我看到了以下代码:
public static TSource ElementAt<TSource>(this IEnumerable<TSource> source, int index)
{
TSource current;
using (IEnumerator<TSource> enumerator = source.GetEnumerator())
{
Label_0036:
if (!enumerator.MoveNext())
{
throw Error.ArgumentOutOfRange("index");
}
if (index == 0)
{
current = enumerator.Current;
}
else
{
index--;
goto Label_0036;
}
}
return current;
}
我认为您可以在没有 goto 语句的情况下编写相同的内容。就像是:
public static TSource ElementAtBis<TSource>(this IEnumerable<TSource> source, int index)
{
using (IEnumerator<TSource> enumerator = source.GetEnumerator())
{
while (enumerator.MoveNext())
{
if (index == 0)
{
return enumerator.Current;
}
else
{
index--;
}
}
throw new ArgumentOutOfRangeException("index");
}
}
所以我想知道为什么 ElementAt 是这样写的。这里有某种约定吗?也许规则是只有一个返回语句是函数的最后一行?或者也许我错过了一些关于性能的东西?或者这是有问题的.NET Reflector?
附带说明一下,ElementAtOrDefault方法不使用 goto 语句:
public static TSource ElementAtOrDefault<TSource>(this IEnumerable<TSource> source, int index)
{
using (IEnumerator<TSource> enumerator = source.GetEnumerator())
{
while (enumerator.MoveNext())
{
if (index == 0)
{
return enumerator.Current;
}
index--;
}
}
return default(TSource);
}