如何在 C# 中从嵌套泛型 class 继承泛型 class

How to inherit a generic class from a nested generic class in C#

我在做作业时遇到了泛型和继承的一些问题。

我有一个通用的红黑树class,因为它是红黑树,所以它的键应该是可比较的,所以

public class RedBlackTree<T> where T : IComparable<T>

然后我想要另一个class,比方说,一个区间树,它是红黑树的增强版本。所以我这样定义间隔:

public class Interval<T> : IComparable where T : IComparable<T>

并且由于区间树确实是一棵以区间为键的红黑树,只是使用了更具体的方法,所以我这样定义 class:

public class IntervalTree<T> : RedBlackTree<Interval<T>> where T : IComparable<T>

但是它不让我这样做,它说的是"cannot implicitly convert Interval<T> to System.IComparable<Interval<T>>",但我也不能写where Interval<T> : IComparable<Interval<T>>

我如何在 C# 中执行此类操作,或者如果在 C# 中无法执行此继承,我应该使用哪些其他模板?

您遇到的错误如下:

Compilation error (line xx, col yy): The type 'Program.Interval<T>' cannot be used as type parameter 'T' in the generic type or method 'Program.RedBlackTree<T>'. There is no implicit reference conversion from 'Program.Interval<T>' to 'System.IComparable<Program.Interval<T>>'.

您需要将错误分开并思考它告诉您的内容。在这种情况下,您声明 IntervalTree 继承自 RedBlackTree<Interval<T>>。但是,您已指定 RedBlackTree 的通用 T 类型必须实现 IComparable<T>。如果您为 Interval 实施 IComparable,错误将消失。 Interval 必须实现用于收缩 RedBlackTree 的接口。

我们拆开来看。我们将停止对所有内容使用 T,因为这会造成混淆。

class RedBlackTree<RBTValue> where RBTValue : IComparable<RBTValue>

好的,所以用于构造 RedBlackTree<> 的每个 RBTValue 必须是 IComparable<RBTValue>.

你想说

 RedBlackTree<Interval<T>>

在某些时候 T。那我们知道什么? Interval<T> 用于 RBTValue,因此必须知道 Interval<T>IComparable<Interval<T>>

因此Interval<>的定义需要是:

class Interval<IValue> : IComparable<Interval<IValue>>

现在,是否任何IValue都需要IComparable<IValue>?如果是,那么我们需要一个约束:

class Interval<IValue> : IComparable<Interval<IValue>> 
where IValue : IComparable<IValue>

确保清楚。这说明了两件事,(1) 一个区间可以与另一个区间进行比较,以及 (2) 一个区间中的值可以与其他值进行比较。

现在我们要定义一个区间树。

class IntervalTree<ITValue> : RedBlackTree<Interval<ITValue>>
where ITValue : IComparable<ITValue>

这是否满足我们的需求? Interval<IValue> 要求 IValue 实施 IComparable<IValue>ITValue 通过约束实现了 IComparable<ITValue>,因此满足要求。

RedBlackTree<RBTValue> 要求 RBTValueIComparable<RBTValue>Interval<ITValue> 实现了 IComparable<Interval<ITValue>>,所以这也很好,我们都准备好了。

综上所述:您可能会考虑将 RBT 作为 成员 而不是 基础 class 来实施 IntervalTree<> 。有没有这样的情况,你要用红黑树多态地处理区间树?如果不是,则无需在 public 表面公开实现细节。

最后,这些类型会变得非常混乱。有关可以更可怕地滥用此模式的方式的更多想法,请参阅

https://blogs.msdn.microsoft.com/ericlippert/2011/02/03/curiouser-and-curiouser/