关于Nullable <t>约束的混淆</t>

时间:2010-04-07 21:59:07

标签: c# .net nullable

向大家致以问候。对不起,如果以前已经问过这个问题(徒劳无功),或者说非常简单,但我无法得到它。 Nullable类型的MSDN definition表示它是以下列方式定义的:

[SerializableAttribute]
public struct Nullable<T>
where T : struct, new()

所以问题非常简单:这个定义怎么可能?或者这只是一个错字?每个值类型都有一个默认构造函数。实际上,当我尝试编译这样的东西时,编译器合理地说,同时应用两个约束是非法的,因为第二个隐含地包含在第一个约束中。

提前致谢。

3 个答案:

答案 0 :(得分:12)

我认为这只是文档中的一个错误。如果查看Reflector中的Nullable<T>类型或使用VS中的“Go To Definition”命令,它只显示struct约束。


修改

我正在考虑这个问题,我做了一点测试:

var attributes = typeof(Nullable<>).GetGenericArguments()[0].GenericParameterAttributes;
Console.WriteLine(attributes);

此代码生成以下输出:

  

NotNullableValueTypeConstraint,DefaultConstructorConstraint

因此,根据反思,T 中的Nullable<T>确实具有new()约束...这意味着即使它在C#中无效,它也是如此必须对CLR有效。

所以文档既正确又错误:T中的Nullable<T>具有“默认构造函数”约束,但它显示的C#声明是错误的......

这实际上并不令人惊讶,因为文档是从程序集元数据(当然还有XML注释)生成的。文档生成器中必定存在错误...

答案 1 :(得分:5)

C#要求值类型具有默认的公共构造函数,但CLR不具有。

如果你用支持这种类型的结构定义的语言定义了一个类型(我相信C ++ / CLI允许这样做),那么调用它的时候会有歧义。

答案 2 :(得分:3)

如果查看IL反汇编,可以看到它确实有一个构造函数约束:

.class public sequential ansi serializable sealed beforefieldinit Nullable<valuetype (System.ValueType) .ctor T>

如果直接从程序集元数据生成文档,可能这是原因吗?