C# .NET Framework内置接口,在构建自定义数据结构时的建议?

C# .NET Framework内置接口,在构建自定义数据结构时的建议?,c#,.net,data-structures,interface,C#,.net,Data Structures,Interface,我正在C#.NET2.0中实现一个AVL二叉树数据结构(可能会迁移到3.5)。我已经达到了这样的程度:它通过了我的初始单元测试,而不需要实现任何框架级接口 但是现在,只要查看FCL,我就会看到一大堆接口,包括非泛型接口和泛型接口,我可以实现这些接口,以确保我的类能够很好地处理语言特性和其他数据结构 目前唯一明显的选择(至少对我来说)是一个枚举样式的接口,允许调用方在foreach循环中使用树,并可能在以后使用Linq。但哪一个(或多个) 以下是我目前正在考虑的接口: IEnumerable和I

我正在C#.NET2.0中实现一个AVL二叉树数据结构(可能会迁移到3.5)。我已经达到了这样的程度:它通过了我的初始单元测试,而不需要实现任何框架级接口

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

目前唯一明显的选择(至少对我来说)是一个枚举样式的接口,允许调用方在foreach循环中使用树,并可能在以后使用Linq。但哪一个(或多个)

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

  • IEnumerable和IEnumerable
  • IEnumerator和IEnumerator
  • i可比较和i可比较
  • IComparer和IComparer
  • ICollection和ICollection
  • IEquatable和IEquatable
  • IEqualityComparer和IEqualityComparer
  • 易克隆的
  • 易变
是否有任何已发布的指南(在线或书籍形式)提供了关于实现哪些框架接口以及何时实现的建议

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

理想情况下,这些建议将为以下问题提供指导:何时使用IComparer或iQualityComparer、IEnumerable或IEnumerator?或者,如果您实现了一个通用接口,您是否也应该实现非通用接口?等等

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

明确的指导是。

它给出了,不,并考虑建议。在中也可以找到大量的接口。

我认为您不会找到一个一刀切的答案,因为这些接口的实现取决于您希望如何使用类

所有这些接口都允许在现有BCL或语言本身中使用类。所以,正如您所说,IEnumerable允许在foreach循环中使用该类

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

换句话说,谁将使用你的课程?您希望他们使用什么BCL框架方法


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

您只需实现希望类具有的版本,即

  • 如果您希望能够枚举项,那么实现
    IEnumerable
    IEnumerable
    ,而不是发明自己的方法
  • 如果您希望能够深度复制一棵树,那么就实现
    ICloneable
    ,而不是发明自己的方法
  • 如果您希望能够比较树的值相等,那么实现所有相等接口
等等。其他要点:

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

您应该知道,这些接口中的一些是相互继承的(
ICollection
IEnumerable
),而接口的通用版本通常需要实现它们的非通用版本
IEnumerator
IEnumerable
已连接(传统上,
IEnumerable
会创建一个
IEnumerator
来执行枚举)

在集合上实现
IComparable
充满了危险(您正在比较集合中的成员吗?),而
icomparaer
是排序方法的帮助界面

ICloneable
有点过时了,但它的目的是创建一个深度拷贝(这对一个集合来说同样充满了危险)

我不同意你的意见

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

如果你实现了一个接口,你应该实现它的所有成员。(参见Liskov替换原理)

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


接口的MSDN文档有点简洁,但您可以随时通过谷歌查看它们的工作原理。

是的,我意识到了这一点。我的问题是有哪些指导原则、惯例等有助于在外观相似的接口之间进行选择(IEquatable、IEqualityComparer)等等。我在我的问题中这样说。我建议,如果你要实现平等,那么就放弃并全部实现它们。是的,这不是一个简单的答案,但我对在类似的接口之间选择的任何指导原则感兴趣,例如。谢谢David,一些有用的提示。你误解了我关于不实现接口的观点。我告诉你一个完整的接口,而不仅仅是某些方法。也就是说,如果你不想提供可克隆的功能,根本不要实现iClonable。我已经改变了我问题中的措辞。