【问题标题】:.NET Framework built-in interfaces, recommendations when building a custom data structure?.NET Framework 内置接口,构建自定义数据结构时的建议?
【发布时间】:2009-11-25 13:27:51
【问题描述】:

我正在 C# .NET 2.0 中实现 AVL 二叉树数据结构(可能会移至 3.5)。我已经达到了它通过我的初始单元测试而无需实现任何框架级接口的程度。

但是现在,只要查看 FCL,我就会看到一大堆接口,包括非泛型和泛型接口,我可以实现这些接口,以确保我的类与语言特性和其他数据结构很好地配合使用。

目前唯一明显的选择(至少对我而言)是枚举样式接口之一,它允许调用者在 foreach 循环中使用树,并且稍后可能与 Linq 一起使用。但是哪一个(或更多)?

以下是我目前正在考虑的接口:

  • IEnumerable 和 IEnumerable<T>
  • IEnumerator 和 IEnumerator<T>
  • IComparable 和 IComparable<T>
  • IComparer 和 IComparer<T>
  • ICollection 和 ICollection<T>
  • IEquatable 和 IEquatable<T>
  • IEqualityComparer 和 IEqualityComparer<T>
  • ICloneable
  • IConvertible

是否有任何已发布的在线指南或书籍形式的指南,提供有关实施哪些框架接口以及何时实施的建议?

显然对于某些接口,如果您不想提供该功能,就不要实现整个接口。但似乎 FCL 类(例如 Collection 类)中存在某些约定,也许我们在构建自定义数据结构时也应该遵循这些约定。

理想情况下,这些建议将就何时使用 IComparer 或 IEqualityComparer、IEnumerable 或 IEnumerator 等问题提供指导?或者,如果你实现了一个泛型接口,你是否也应该实现非泛型接口?等等。

或者,如果您可以根据自己的经验提供指导,那同样有用。

【问题讨论】:

    标签: c# .net data-structures interface


    【解决方案1】:

    您应该知道,其中一些接口相互继承(ICollection<T>IEnumberable<T>),并且接口的通用版本通常需要实现它们的非通用版本。 IEnumeratorIEnumerable 已连接(IEnumerable 传统上会创建一个 IEnumerator 来进行枚举)

    在集合上实现IComparable<T> 充满危险(您是在比较集合中的成员吗?),而IComparer<T> 是排序方法的辅助接口。

    ICloneable 有点过时了——但它的目的是创建一个深层副本(同样,这对集合来说充满了危险。

    我会反对你的

    显然对于某些接口,如果您不想提供该功能,就不要实现它们。

    如果你实现一个接口,你应该实现它的所有成员。 (见里氏替换原则)

    为集合实现IConvertible 似乎也很奇怪——您可能更喜欢实现ISerializable

    接口的 MSDN 文档有点简洁,但您可以随时在 Google 上搜索它们以了解它们是如何工作的。

    【讨论】:

    • 谢谢大卫,一些有用的提示。您误解了我关于不实现接口的观点。我的意思是整个界面,而不仅仅是某些方法。即,如果您不想提供可克隆功能,则根本不要实现 ICLoneable。我已经更改了问题中的措辞。
    【解决方案2】:

    确切的指南是Framework Design Guidelines
    它给出了做、不做和考虑的建议。 MSDN 中也有很多内容。

    【讨论】:

      【解决方案3】:

      我认为您不会找到一个万能的解决方案,因为这些接口的实现取决于您希望如何使用您的类。

      提供所有这些接口是为了允许使用现有 BCL 或语言本身中的类。因此,正如您所说, IEnumerable 允许在 foreach 循环中使用该类。

      实现其中的每一个都取决于您的库的使用方式。例如,ICloneable 直接适用于远程处理用户,有时也适用于 ORM 用户。如果您的课程在该环境中有意义,那么您将通过实施它来帮助您的用户。

      换一种说法:谁会使用你的课程?您希望他们使用哪些 BCL 框架方法?

      (此外,许多泛型接口本身实现了非泛型版本,例如 IEnumerable 实现了 IEnumerable,而 IEnumerator 实现了 IEnumerator。)

      【讨论】:

      • 是的,这不是一个简单的答案,但我对在相似的声音界面之间进行选择的任何指南感兴趣,例如。
      【解决方案4】:

      您只需实现您希望班级拥有的那些,即

      • 如果您希望能够枚举项目,请实现 IEnumerableIEnumerable<T>,而不是发明自己的方法。
      • 如果您希望能够深度复制一棵树,请实现ICloneable,而不是发明自己的方法。
      • 如果您希望能够比较树的值是否相等,请实现所有相等接口。

      等等。其他要点:

      • 应以特定方式实现某些接口,以避免在调用它们的代码中出现“意外”行为。特别是相等接口必须彼此 100% 一致,并且必须与 System.Object 虚拟相等方法保持一致。
      • 当同一接口存在通用和非通用版本时,实现两者总是有用的。

      【讨论】:

      • 是的,我意识到了这一点。我的问题是哪些准则、约定等有助于在外观相似的界面(IEquatable、IEqualityComparer)等之间进行选择。我在我的问题中这么说。
      • 我建议,如果您要实现平等,请全力以赴并全部实现。
      猜你喜欢
      • 2016-05-21
      • 2013-03-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多