简体   繁体   English

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

[英]Why we can’t use sealed classes as generic constraints?

Can you guess what is the reason to not allow sealed classes for type-constraints in generics? 你能猜出在泛型中不允许使用密封类进行类型约束的原因是什么? I only have one explanation is to give opportunity to use naked constraints. 我只有一个解释是给机会使用裸约束。

If the class is sealed it cannot be inherited. 如果类是密封的,则不能继承。 If it cannot be inherited it'd be the only type valid for the generic type argument [assuming if allowed to be a type argument]. 如果它不能被继承,它将是泛型类型参数有效的唯一类型[假设允许为类型参数]。 If it is the only generic type argument then there's no point in making it generic! 如果它是唯一的泛型类型参数,那么将它变为通用就没有意义了! You can simply code against the type in non-generic class. 您可以简单地针对非泛型类中的类型进行编码。

Here's some code for this. 这是一些代码。

public class A
{
    public A() { }
}

public sealed class B : A
{
    public B() { }
}

public class C<T>
        where T : B
{
    public C() { }
}

This will give compiler error: 'B' is not a valid constraint. 这将给出编译器错误: 'B'不是有效约束。 A type used as a constraint must be an interface, a non-sealed class or a type parameter. 用作约束的类型必须是接口,非密封类或类型参数。

In addition to this, You can also not have a static class as generic type-constraint. 除此之外,您还可以将静态类作为泛型类型约束。 The reason is simple. 原因很简单。 Static classes are marked as abstract and sealed in compiled IL which can be neither instantiated nor inherited. 静态类被标记为抽象密封在已编译的IL中 ,既不能实例化也不能继承。

Here's the code for this. 这是代码。

public class D<T>
        where T : X
{
    public D() { }
}

public static class X
{
}

This will give compiler error: 'X': static classes cannot be used as constraints. 这将给编译器错误: 'X':静态类不能用作约束。

Are you talking about something like this: 你在谈论这样的事情:

class NonSealedClass
{
}

class Test<T> where T : NonSealedClass
{
}

Because it's perfectly legal. 因为它完全合法。

Honestly, I don't quite see the point of it. 老实说,我不太明白这一点。

As this.__curious_geek points out in his answer , a sealed class cannot be inherited and so using one as a constraint might seem nonsensical. 正如这个.__ curious_geek在他的回答中指出的那样 ,密封的类不能被继承,因此使用一个作为约束似乎是荒谬的。

But there's no guarantee that a sealed class will never be "unsealed" -- ie, that the developer might rearrange its implementation to make it more amenable to inheritance and then remove the sealed modifier from the class definition (or just flat-out remove the sealed keyword for no reason at all). 但是不能保证密封的类永远不会被“启封” - 也就是说,开发人员可能会重新安排其实现以使其更适合继承,然后从类定义中删除sealed修饰符(或者只是将其删除sealed关键字无缘无故)。

I know a lot of developers actually encourage this practice: not removing the sealed keyword per se, but rather adding the sealed keyword liberally and only supporting inheritance when the decision to do so is made explicitly (and at this point, yes, removing the sealed keyword). 我知道很多开发人员实际上都鼓励这种做法:不要删除sealed关键字本身,而是自由地添加 sealed关键字,只有在明确做出决定时才支持继承(此时,是的,删除sealed关键词)。

So I'm not sure why you couldn't use the type of a sealed class as a generic constraint. 所以我不确定为什么你不能使用密封类的类型作为通用约束。 After all, you could always use the type of a class that just happens to not have any derived classes, even though it's not sealed. 毕竟,你总是可以使用恰好没有任何派生类的类的类型,即使它没有被密封。 The two scenarios don't seem all that different to me. 这两种情况对我来说似乎并没有什么不同。

I'm probably missing something, though. 不过,我可能会遗漏一些东西。 I'm sure Eric Lippert could give a pretty killer explanation. 我相信Eric Lippert可以给出一个相当杀手的解释。

A naked constraint is where one generic type inherits from another eg 裸约束是一个泛型类型从另一个继承的例如

where X:Y

One generic parameter derives from another generic parameter 一个通用参数派生自另一个通用参数

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

So the class cannot be sealed. 因此班级无法封存。

You can also inherit from generics in the normal way so you would not want them sealed. 您也可以以正常方式继承泛型,因此您不希望它们被密封。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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