【问题标题】:C#: Where to implement a custom IEnumerator<T>C#:在哪里实现自定义 IEnumerator<T>
【发布时间】:2009-10-03 13:24:10
【问题描述】:

假设我有一个实现IEnumerable&lt;T&gt; 的类。它目前在GetEnumerator() 方法中使用yield 关键字。但是现在我需要做更多的事情,例如我想自己清理一下。为此,除非我忽略了什么,否则我需要实现IEnumerator&lt;T&gt; 接口。但是你说我应该在哪里做呢?

类本身是否应该实现它并且GetEnumerator()返回this?还是将其隐藏在私人课程中会更好?还是应该只是一个完全不同的班级?对此有哪些常见做法?

【问题讨论】:

    标签: c# ienumerable ienumerator


    【解决方案1】:

    如果你需要做的就是在枚举数被释放时清理一些资源,比如在foreach 循环的末尾,那么你可以用你拥有的东西来做,只需添加一个 try/finally 块你的迭代器方法。

    像这样:

    public IEnumerator<T> GetEnumerator()
    {
        try
        {
            // your iterator code here
        }
        finally
        {
            // cleanup code here
        }
    }
    

    仅此而已。

    【讨论】:

    • 我以为你不能在 try 块内让步?
    • @csharptest.net - 如果它后面只有一个 finally 块,你可以。这是不允许的捕获。
    • 太棒了。不知道这甚至是可能的。经过测试,yield return 可以存在于 try 块中。 但是它不能存在于finally 块中。而且,就像@Earwicker 指出的那样,它不能存在于具有catch 块的try 块中。
    • @Earwicker Doh! -1 对我来说,我不知道(显然)感谢您提供的信息:)
    • 我最近写了一系列文章,解释了为什么我们对收益回报的去向有这些限制。如果您有兴趣,请参阅blogs.msdn.com/ericlippert/archive/tags/Iterators/default.aspx
    【解决方案2】:

    我会选择 IEnumerator 的课程。这将需要存储不属于集合的状态(当前位置),而是枚举过程的一部分。

    【讨论】:

    • 您可能想阅读yield return - 看起来您编写了一个方法,但实际上您正在生成一个带状态的类。
    • @Earwicker,是的,我知道。所以这就是我提出私人课程建议的原因。因为我猜这最终会是相似的。虽然我真的不知道:p
    【解决方案3】:

    您可能根本不需要为此编写课程。一个迭代器方法可以返回IEnumerable&lt;T&gt;,所以如果你的类只需要实现IEnumerable&lt;T&gt;而不需要其他任何东西,只需为整个事情编写一个迭代器方法。

    如果没有,并且您必须坚持使用实现 IEnumerable&lt;T&gt; 的外部类,通过使用迭代器方法来执行 GetEnumerator,那么您不必在迭代后做任何难以清理的事情。

    IEnumerator&lt;T&gt; 派生自 IDisposable。迭代器方法通过执行finally 块或最后一个yield return 之后的任何代码来实现Dispose

    【讨论】:

    • 最后一次收益返回后的代码?那将如何工作?特别是如果yield returns 处于无限循环中...
    • 我的措辞真的很糟糕!如果可以访问最后一个yield return 之后的代码,则执行它,但在最后一次调用IEnumerator.MoveNext 时执行,而不是Dispose。如果收益返回处于无限循环中,则该循环之后的代码将无法访问,编译器会告诉您。如果不是,则在调用者枚举集合中的所有项目后执行该代码。因此,无论枚举是完成还是放弃,都使用 finally 块来执行,如果您希望它仅在不放弃枚举的情况下执行,则将代码放在方法的末尾。
    猜你喜欢
    • 1970-01-01
    • 2018-02-15
    • 2020-06-23
    • 1970-01-01
    • 1970-01-01
    • 2012-07-22
    • 2016-06-21
    • 1970-01-01
    • 2012-12-06
    相关资源
    最近更新 更多