代码之家  ›  专栏  ›  技术社区  ›  JSBÕ±Õ¸Õ£Õ¹

为什么.NET没有双向枚举器?

  •  10
  • JSBÕ±Õ¸Õ£Õ¹  · 技术社区  · 15 年前

    它被问了几次,所以如何实现双向枚举器( here , here )我的问题不是 怎样 (大多数情况下这是微不足道的),但是 为什么? .NET平台中不存在此类类型。

    public interface IBidirectionalEnumerator<T> : IEnumerator<T>
    {
        bool MovePrev();
    }
    

    显然,有许多集合类型无法实现这一点,因为 MoveNext() 具有破坏性或更改基础集合的状态。但是相反,很多类型 可以 执行这个琐碎的( List , IList , LinkedList , array )

    为什么不存在这种类型?

    6 回复  |  直到 12 年前
        1
  •  3
  •   Amy B    15 年前
    • IEnumerator支持c foreach语句以及其他语言的循环构造。
    • 没有ibDirectionEnumerator支持的语句或通用编程习惯用法。
        2
  •  4
  •   Mehrdad Afshari    15 年前

    当你设计一个框架时,你必须决定在不同的抽象层次上做事情。权衡是,如果您选择在高抽象级别公开事物,那么您将以失去对事物的细粒度控制为代价实现泛化。如果您选择在较低的抽象级别公开内容,那么您的概念也不能被概括,但是您可以在较低的级别控制细节。

    这是一个设计决策。实现这两者都将是昂贵的,并且会使框架更加膨胀,并且在添加特性时需要同时支持这两者。将来需要保持向后兼容性。在不确定BCL是否有显著好处的情况下,将您能想到的所有内容添加到BCL中是不明智的。

        3
  •  2
  •   Maximilian Mayerl    15 年前

    因为要么没人考虑过,要么没人认为它会特别有用,要么因为没有足够的预算,要么…

    这不是真的必要,是吗?您可以自己轻松地实现它。也许BCL团队认为它不值得实施、测试、记录等的痛苦。永远不要低估一个特性的成本,它听起来“容易”,但它确实有成本。

    特别是因为没有人实现的单一接口看起来很奇怪,不是吗?您将期望列表、数组等实现接口,这最终是相当多的工作。

        4
  •  2
  •   yfeldblum    15 年前

    显然,有许多集合类型无法实现这一点,因为 MoveNext() 具有破坏性或更改基础集合的状态。

    移动下一个() 是非破坏性的。实际上,如果基础集合的状态在 IEnumerator 创建时间 MOVENTXEL() 被呼叫,呼叫 MOVENTXEL() 会失败。

    目的 迭代器 如果集合具有本机顺序,则按集合的本机顺序对集合中的所有项进行一次迭代。 迭代器 不打算作为一个集合导航设备,如一个可能在C++中找到的。

        5
  •  1
  •   gn22    15 年前

    还有,这其中的动机是什么?“向后”迭代的语言支持?

    迭代器模式不太重视一组元素的“方向性”概念。它是一个简单的模式,提供了一个简单的接口来迭代一个集合。

        6
  •  1
  •   supercat    14 年前

    更大的问题是,为什么.NET不实现IReadableByIndex,而IReadableByIndex又将由IList继承。这样的类型不会为生成读写IList实现所需的工作添加任何内容,并且会减少生成只读实现所需的工作(将实现IReadableByIndex,而不是IList)。

    然而,思考这样的“为什么”并不太有用。.NET就是它。补救.NET 5.0情况的唯一方法是允许声明实现读写属性的接口可以被视为隐式实现只读版本(以便允许IList继承协变的IReadableByIndex而不必添加显式get方法)。