繁体   English   中英

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

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM