框架中的某些类有效地将特殊特征传递给从它们派生的所有类型,但它们本身并不具备这些特征。CLR 本身并没有禁止使用这些类作为约束,但是受约束的泛型类型不会像具体类型那样获得非继承特性。C# 的创建者决定,因为这样的行为可能会让一些人感到困惑,并且他们看不到它有任何用处,所以他们应该禁止这样的约束,而不是允许它们像在 CLR 中那样行事。
例如,如果允许一个人写void CopyArray<T>(T dest, T source, int start, int count)
:可以将dest
和传递source
给期望类型为参数的方法System.Array
;此外,人们将获得兼容数组类型的编译时验证dest
,source
但无法使用[]
运算符访问数组的元素。
无法Array
用作约束通常很容易解决,因为void CopyArray<T>(T[] dest, T[] source, int start, int count)
在前一种方法可以工作的几乎所有情况下都可以工作。但是,它确实有一个弱点:前一种方法可以在一个或两个参数是类型的System.Array
情况下工作,而拒绝参数是不兼容的数组类型的情况;添加两个参数都是类型的重载System.Array
将使代码接受它应该接受的其他情况,但也会使其错误地接受它不应该接受的情况。
我发现取缔大多数特殊限制的决定令人讨厌。唯一具有零语义意义的将是System.Object
[因为如果这是合法的约束,任何东西都会满足它]。 System.ValueType
可能不会很有用,因为类型的引用ValueType
与值类型并没有太多共同之处,但在涉及反射的情况下它可能有一些价值。两者System.Enum
都有System.Delegate
一些实际用途,但是由于 C# 的创建者没有想到它们,因此它们被无缘无故地取缔了。