[英]Why we can’t use sealed classes as generic constraints?
你能猜出在泛型中不允许使用密封类进行类型约束的原因是什么? 我只有一个解释是给机会使用裸约束。
如果类是密封的,则不能继承。 如果它不能被继承,它将是泛型类型参数有效的唯一类型[假设允许为类型参数]。 如果它是唯一的泛型类型参数,那么将它变为通用就没有意义了! 您可以简单地针对非泛型类中的类型进行编码。
这是一些代码。
public class A
{
public A() { }
}
public sealed class B : A
{
public B() { }
}
public class C<T>
where T : B
{
public C() { }
}
这将给出编译器错误: 'B'不是有效约束。 用作约束的类型必须是接口,非密封类或类型参数。
除此之外,您还可以将静态类作为泛型类型约束。 原因很简单。 静态类被标记为抽象并密封在已编译的IL中 ,既不能实例化也不能继承。
这是代码。
public class D<T>
where T : X
{
public D() { }
}
public static class X
{
}
这将给编译器错误: 'X':静态类不能用作约束。
你在谈论这样的事情:
class NonSealedClass
{
}
class Test<T> where T : NonSealedClass
{
}
因为它完全合法。
老实说,我不太明白这一点。
正如这个.__ curious_geek在他的回答中指出的那样 ,密封的类不能被继承,因此使用一个作为约束似乎是荒谬的。
但是不能保证密封的类永远不会被“启封” - 也就是说,开发人员可能会重新安排其实现以使其更适合继承,然后从类定义中删除sealed
修饰符(或者只是将其删除sealed
关键字无缘无故)。
我知道很多开发人员实际上都鼓励这种做法:不要删除sealed
关键字本身,而是自由地添加 sealed
关键字,只有在明确做出决定时才支持继承(此时,是的,删除sealed
关键词)。
所以我不确定为什么你不能使用密封类的类型作为通用约束。 毕竟,你总是可以使用恰好没有任何派生类的类的类型,即使它没有被密封。 这两种情况对我来说似乎并没有什么不同。
不过,我可能会遗漏一些东西。 我相信Eric Lippert可以给出一个相当杀手的解释。
裸约束是一个泛型类型从另一个继承的例如
where X:Y
一个通用参数派生自另一个通用参数
class Foo<T>
{
Foo<S> SubsetFoo<S>() where S : T { }
}
因此班级无法封存。
您也可以以正常方式继承泛型,因此您不希望它们被密封。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.