C#:IEnumerator在 using 语句中

发布于 2024-07-22 07:33:48 字数 958 浏览 9 评论 0原文

我很好奇 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

缱倦旧时光 2024-07-29 07:33:48

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> extends IDisposable, so you should have it in a using statement. foreach does this automatically. (The non-generic IEnumerator doesn't extend IDisposable but the C# compiler still generates code to call Dispose 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:

  • If the sequence is empty, return the fallback item
  • If the sequence has exactly one item, return it
  • If the sequence has more than one item, throw an exception

PS: Nice to see MoreLinq is getting some attention :)

—━☆沉默づ 2024-07-29 07:33:48

如果不调用 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文