泛型类类型约束,泛型类具有另一个约束

时间:2021-04-21 16:30:31

标签: c# generics generic-constraints

假设我有一个泛型类

public class G<T> {
}

并且我想将最终类声明为

public class F<T> where T : G<T> {
}

这似乎是可能的,但是如果我想让任务复杂化并像这样向 G 类添加约束怎么办

public class A {
}

public class DA : A {
}

public class DB : A {
}

public class G<T> where T : A {
}

最后我想这样做

public class F<T> where T : G<T> {
}

那不起作用,它说 T 必须是 A 类型,这是可以理解的,看起来我可以像这样重写它

public class F<T, U> where T : G<U> where U : A {
}

但在这种情况下,用法有一个多余的声明

public class DF : F<G<DA>, DA> {
}

在使用 F 类时我必须重复 DA 两次,即使很清楚如果我使用 G 作为泛型类型 G 的泛型类型是 DA。有没有办法避免这种冗余?

1 个答案:

答案 0 :(得分:0)

<块引用>

最后我想这样做

public class F<T> where T : G<T> {
}

但这似乎没有多大意义。您希望 FT 参数化,G<X> 必须是 X,其中 T 再次是 G<X>,即 X,其中 {{1 }} 又是 T 等等......这是一个递归定义。

我认为您实际想要定义的内容类似于(所有示例都是无效的 C#)

public class F<T1<T2>> where T1 : G<T2> where T2 : A {
}

也许

public class F<T1> where T1 : G<T2> where T2 : A {
}

也许

public class F<G<T>> where T : A {
}

那些“泛型的泛型”被称为高级类型,但不幸的是,C# 不支持它们。例如 Haskell 和其他一些函数式语言也是如此。

有一个 C# library 模仿 HKT,它使用您找到的解决方法:两次指定内部类型。