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

Gri*_*uev 22 .net c# generics constraints

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

thi*_*eek 42

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

这是一些代码.

public class A
{
    public A() { }
}

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

public class C<T>
        where T : B
{
    public C() { }
}
Run Code Online (Sandbox Code Playgroud)

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

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

这是代码.

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

public static class X
{
}
Run Code Online (Sandbox Code Playgroud)

这将给编译器错误:'X':静态类不能用作约束.

  • 但现在绝对可以实例化C <B>以外的任何类型的C对象.因为B是密封的,所以它没有子类,因此没有其他类型匹配"where T:B".因此,类型T将始终为B; 否则,约束失败.如果您的通用代码受到约束以使其仅适用于一种类型,那么它仍然是通用的吗?:) (9认同)
  • 使用多个约束的情况如何?即:`where T : SomeSealedClass, SomeNonSealedClass` - 例如,如果两个约束都有相似的方法/成员,但实际上没有继承同一个类或使用公共接口,那么你的选择是什么? (2认同)

Avi*_* P. 5

你在谈论这样的事情:

class NonSealedClass
{
}

class Test<T> where T : NonSealedClass
{
}
Run Code Online (Sandbox Code Playgroud)

因为它完全合法.

  • 你想用这个代码片段来解释什么? (2认同)