C#:IEnumerator在 using 语句中
我很好奇 SingleOrFallback
方法是如何在 MoreLinq 并发现了一些我以前没有见过的东西:
public static T SingleOrFallback<T>(this IEnumerable<T> source, Func<T> fallback)
{
source.ThrowIfNull("source");
fallback.ThrowIfNull("fallback");
using (IEnumerator<T> iterator = source.GetEnumerator())
{
if (!iterator.MoveNext())
{
return fallback();
}
T first = iterator.Current;
if (iterator.MoveNext())
{
throw new InvalidOperationException();
}
return first;
}
}
为什么 IEnumerator
出现在 using
语句中? 在 IEnumerable
上使用 foreach
时是否也应该考虑这一点?
附带问题:这个方法到底是做什么的? 当源序列不恰好包含一项时,它是否返回后备项?
I was curious to see how the SingleOrFallback
method was implemented in MoreLinq and discovered something I hadn't seen before:
public static T SingleOrFallback<T>(this IEnumerable<T> source, Func<T> fallback)
{
source.ThrowIfNull("source");
fallback.ThrowIfNull("fallback");
using (IEnumerator<T> iterator = source.GetEnumerator())
{
if (!iterator.MoveNext())
{
return fallback();
}
T first = iterator.Current;
if (iterator.MoveNext())
{
throw new InvalidOperationException();
}
return first;
}
}
Why is the IEnumerator<T>
in a using
statement? Is this something that should be thought about when using the foreach
on an IEnumerable<T>
also?
Side question: What does this method do exactly? Does it return the fallback item whenever the source sequence does not contain exactly one item?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
IEnumerator
扩展了IDisposable
,因此您应该将其放在 using 语句中。foreach
自动执行此操作。 (非泛型IEnumerator
不会扩展IDisposable
,但 C# 编译器仍然生成有条件调用Dispose
的代码这是 C# 1.0 和 1.2 之间的(少数)更改之一,由于某种原因,1.2 是随 .NET 1.1 一起发布的版本。) .aspx" rel="noreferrer">这里有一篇文章解释了为什么这在迭代器块的上下文中很重要。
至于该方法的作用:
PS:很高兴看到 MoreLinq 得到了一些关注: )
IEnumerator<T>
extendsIDisposable
, so you should have it in a using statement.foreach
does this automatically. (The non-genericIEnumerator
doesn't extendIDisposable
but the C# compiler still generates code to callDispose
conditionally. This was one of the (few) changes between C# 1.0 and 1.2, where 1.2 is the version shipping with .NET 1.1, for some reason.)Here's an article explaining why this is important in the context of iterator blocks.
As for what the method does:
PS: Nice to see MoreLinq is getting some attention :)
如果不调用 Dispose,某些枚举器的行为会很糟糕; 对于非泛型和泛型来说都是如此(非泛型要求代码要么鸭子类型 Dispose 调用,要么强制转换为 IDisposable,然后调用 IDisposable.Dispose)。 确保 IEnumerator 对象被释放是一个习惯问题; 我认为对于接受未知类型的 IEnumerable 的任何例程的正确性都是必要的。
Some enumerators will behave badly if Dispose is not called; this is just as true for the non-generic ones as the generic ones (the non-generic ones require that code either duck-type the Dispose call or else cast to IDisposable and then call IDisposable.Dispose). It is good as a matter of habit to ensure that IEnumerator objects get disposed; I would consider it necessary for correctness of any routine which accepts an IEnumerable of unknown type.