编译器如何将Nullable <t>识别为“特殊类型”?</t>

时间:2014-02-14 10:36:59

标签: c# .net generics clr nullable

Nullable<T>是一个具有以下定义的结构:

public struct Nullable<T> where T : struct

其中struct是一个类型约束,因此T被约束为(根据规范§4.4.4):

  • struct type或enum type
  • 不是可以为空的类型。

查看Nullable<T>的源代码,没有特殊属性(期望[Serializable]),那么编译器如何将其识别为“可空类型”?

回应以下评论:

intInt32别名

  

(§4.1.4)简单类型通过保留字识别,但这些   对于预定义的结构类型,保留字只是别名   系统命名空间

T?Nullable<T>简写

  

(§4.1.10) - 可空类型写为T ?,其中T是底层   类型。对于System.Nullable,这个语法是简写,两者   表格可以互换使用。

这似乎是一个明显的差异,下面没有反映出来。

那么编译器如何识别一个简单的结构(没有特殊代码)作为“可空类型”,结构名称?

1 个答案:

答案 0 :(得分:2)

基于Shared Source CLI 2.0Nullable<T>通过PREDEFTYPEDEF宏制作为“特殊”,其名称为“System.Nullable”并将其映射到属性{ {1}}在整个编译器的其余部分进行检查。

关于PT_G_OPTIONALint等的别名,请参阅“好名字”栏。

来自System.Int32

sscli20\csharp\inc\predeftype.h

然后在其他地方使用它:

来自// id full type name required simple numer AggKind fund type elementtype, nice name, zero, quasi simple numer, attribute arg size serialization type, predef attribute, arity, in mscorlib) PREDEFTYPEDEF(PT_BYTE, "System.Byte", 1, 1, 1, Struct, FT_U1, ELEMENT_TYPE_U1, L"byte", 0, 0, 1, SERIALIZATION_TYPE_U1, PA_COUNT, 0, 1) PREDEFTYPEDEF(PT_SHORT, "System.Int16", 1, 1, 1, Struct, FT_I2, ELEMENT_TYPE_I2, L"short", 0, 0, 2, SERIALIZATION_TYPE_I2, PA_COUNT, 0, 1) PREDEFTYPEDEF(PT_INT, "System.Int32", 1, 1, 1, Struct, FT_I4, ELEMENT_TYPE_I4, L"int", 0, 0, 4, SERIALIZATION_TYPE_I4, PA_COUNT, 0, 1) PREDEFTYPEDEF(PT_LONG, "System.Int64", 1, 1, 1, Struct, FT_I8, ELEMENT_TYPE_I8, L"long", &longZero, 0, 8, SERIALIZATION_TYPE_I8, PA_COUNT, 0, 1) // ... snip ... // Nullable<T> PREDEFTYPEDEF(PT_G_OPTIONAL, "System.Nullable", 0, 0, 0, Struct, FT_STRUCT, ELEMENT_TYPE_END, NULL, 0, 0, 0, 0, PA_COUNT, 1, 1)

sscli20\csharp\sccomp\nullable.cpp

对于阅读此问题的人,您可能是Shared Source CLI 2.0 Internals的目标受众群体,该版本是作为免费电子书发布的。