【问题标题】:IEnumerable and IEnumerator in the same class, bad idea?IEnumerable 和 IEnumerator 在同一个类中,坏主意?
【发布时间】:2011-01-31 22:16:05
【问题描述】:

这是个坏主意吗?

Private Class GH_DataStructureEnumerator(Of Q As Types.IGH_Goo)
  Implements IEnumerable(Of Q)
  Implements IEnumerator(Of Q)
  ....
  ....
  'Current, MoveNext, Reset etc.'
  ....
  ....

  Public Function GetEnumerator_Generic() As IEnumerator(Of Q) _
                  Implements IEnumerable(Of Q).GetEnumerator
    Return Me
  End Function
End Class

此类仅作为 IEnumerable(Of T) 只读属性可见,它为我节省了一个包装 IEnumerator(Of T) 的附加类。但不知何故,这似乎是错误的。有没有更好的办法?

【问题讨论】:

    标签: c# ienumerable ienumerator


    【解决方案1】:

    绝对是个坏主意。特别是,这意味着对GetEnumerator 的两次调用将返回对同一个对象的引用——当它们应该返回独立迭代器时。

    话虽如此,如果您使用迭代器块,C# 编译器将生成实现这两种类型的类……但它会竭尽全力确保它正确无误。我建议你不要让自己经历那种痛苦:)

    【讨论】:

    • 乔恩,我的人生目标是避免痛苦,感谢您的提醒。
    【解决方案2】:

    这是一个坏主意,因为如果有人试图同时多次枚举您的集合,解决方案就会崩溃。

    例如:这会以某种方式中断

    For Each cur1 in yourObj 
      For Each cur2 in yourObj
        Console.WriteLine("{0} - {1}", cur1,cur2)
      Next
    Next
    

    【讨论】:

    • 或者甚至不是同时,很有可能:)
    【解决方案3】:

    来自Implementing IEnumerable

    请提供一个 GetEnumerator() 方法,该方法返回一个名为“Enumerator”的嵌套公共结构

    顺便说一句,本网站由布拉德·艾布拉姆斯维护,他是 Framework Design Guidelines 的作者之一。

    【讨论】:

    • 我从不喜欢这个特别的建议 - 它鼓励可变结构,它可以以邪恶的方式表现。
    • @Jon - 这是一个很好的观点,但我认为在这种情况下这并不是最糟糕的想法。这绝对是性能(结构体的内存压力较小)和可变结构体之间的权衡,这可能会在应用程序中引入怪异。我认为,鉴于大多数开发人员不直接使用枚举器实例,因此将其设为可变结构是对性能优势的一个很好的折衷。但总的来说,我同意应该避免使用可变结构。
    • Brad 非常清楚地做出了权衡:实现此模式涉及拥有一个额外的公共类型(枚举器)和几个额外的公共方法,这些方法实际上只是出于基础设施的原因。这些类型增加了 API 的复杂性,并且必须进行记录、测试、版本控制等。因此,只有在性能至关重要的情况下才应遵循此模式。因此,这应该不 大部分时间在性能不太重要的情况下使用。
    • @Mehrdad - 很公平,但我认为实现IEnumerator 的类型并不会真正创建那么 多的API 复杂性。不过好点:)
    • 我建议 IEnumerable 应该返回一个类而不是一个结构,尽管出于性能原因,拥有一个与返回一个结构的 IEnumerable 无关的 GetEnumerator 方法可能会有所帮助。如果 GetEnumerator 方法存在并返回一个结构,VB.net 和 C# 都会对它进行回避类型以避免装箱;但是,通过 IEnumerable 调用 GetEnumerator 将需要将枚举器强制转换为装箱的 IEnumerator,从而消除了结构体所具有的任何性能优势。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-01
    相关资源
    最近更新 更多