为什么我们不能使用密封类作为通用约束?

你能猜出在generics中不允许使用密封类进行类型约束的原因是什么? 我只有一个解释是给机会使用裸约束。

如果类是密封的,则不能inheritance。 如果它不能被inheritance,那么它就是唯一对generics类型参数有效的类型[假设允许它是一个类型参数]。 如果它是唯一的generics类型参数,那么将其作为通用就没有意义了! 您可以简单地针对非generics类中的类型进行编码。

这是一些代码。

 public class A { public A() { } } public sealed class B : A { public B() { } } public class C where T : B { public C() { } } 

这将给编译器错误: ‘B’不是有效的约束。 用作约束的类型必须是接口,非密封类或类型参数。

除此之外,您还可以将静态类作为generics类型约束。 原因很简单。 静态类被标记为抽象密封在已编译的IL中 ,既不能实例化也不能inheritance。

这是代码。

 public class D where T : X { public D() { } } public static class X { } 

这将给编译器错误: ‘X’:静态类不能用作约束。

你在谈论这样的事情:

 class NonSealedClass { } class Test where T : NonSealedClass { } 

因为它完全合法。

老实说,我不太明白这一点。

正如这个.__ curious_geek在他的回答中指出的那样 ,密封的类不能被inheritance,因此使用一个作为约束似乎是荒谬的。

但是不能保证密封类永远不会“未密封” – 即,开发人员可能会重新安排其实现以使其更适合inheritance,然后从类定义中删除sealed修饰符(或者只是平坦删除sealed关键字无缘无故)。

我知道很多开发人员实际上都鼓励这种做法:不要删除sealed关键字本身,而是自由地添加 sealed关键字,只有在明确做出决定时才支持inheritance(此时,是的,删除sealed关键词)。

所以我不确定为什么你不能使用密封类的类型作为通用约束。 毕竟,你总是可以使用恰好没有任何派生类的类的类型,即使它没有被密封。 这两种情况对我来说似乎并没有什么不同。

不过,我可能会遗漏一些东西。 我相信Eric Lippert可以给出一个相当杀手级的解释。

裸约束是一种generics类型从另一种inheritance的例子

 where X:Y 

一个通用参数派生自另一个通用参数

 class Foo { Foo SubsetFoo() where S : T { } } 

因此class级无法封存。

您也可以以正常方式inheritancegenerics,因此您不希望它们被密封。