为什么这些“特殊课程”到底是什么?

时间:2015-05-06 09:07:17

标签: c# generics generic-constraints

在阅读this question询问“特殊班级”究竟是什么之后,我留下了六个班级System.ObjectSystem.ArraySystem.Delegate,{{选择了1}}和System.Enum,并将hard-coded作为特殊类,防止它们被用作泛型类或方法的约束。

可以想象为什么System.ValueType在那里;所有类都继承System.Object,因此不需要将其作为约束包含在内。我不清楚的是为什么其他人被选为此特殊课程类别的一部分。

PS :当尝试将它们用作约束时,特殊类会引发编译错误CS0702。

1 个答案:

答案 0 :(得分:7)

在将通用约束甚至泛型添加到.NET框架并将其支持添加到C#语言之前,这些类已经不同了。

他们每个人的共同点是,从他们那里继承的不同于其他类型:

System.Object :您不能在C#中继承此内容。

System.Array :您可以通过创建现有类型的数组(Array x = new int[2];等)继承此内容。

System.Delegate :您通过创建delegate(然后从MulticastDelegate派生,也是“特殊类型”继承自此,派生自{ {1}})。

Delegate :您通过创建System.Enum继承此内容。

enum :您通过创建System.ValueType继承此内容。

现在,请注意除了struct之外,通用约束都是关于接口的继承或实现(在很多方面类似于继承)。实际上,其他限制是您不能使用指针类型,并且您不能使用密封类型;两种情况下你无法获得派生类型(尽管禁止密封类型主要是因为你可能在你不需要时创建一个通用类型或方法,并试图保护你自己)

当面对有关继承的特殊情况时,基于继承功能(作为约束)的代码本身可能必须涉及特殊情况。这些特殊情况以最简单的方式处理:禁止它们。

在许多情况下,该值也较少:

new()由于唯一无法转换为System.Object的类型是指针类型,并且这些类型无论如何都不能用作通用参数,任何此类约束是多余的。

System.Object :您可以根据元素类型进行定义:System.Array等。

void DoSomethingWithArray<T>(T[] array)这样会很有用,但在很多情况下我们可以根据参数和/或返回类型进行定义,但有些情况下这种情况无法捕获。

System.Delegate会很有用。

System.Enum已经处理过;约束为System.ValueType。相反,我们也可以约束struct来排除这种情况,所以我们实际上是一个“不是继承自......”的选项,我们没有其他选择。

这并不是否认能够根据classDelegateMulticastDelegate进行约束是没有用的(可能最重要的是我们Enum),但在证明额外工作以支付这些类型的合理性方面,其他工作几乎没有带来任何好处,因此减少了限制的好处。