Nullable<T>
是一个具有以下定义的结构:
public struct Nullable<T> where T : struct
其中struct
是一个类型约束,因此T被约束为(根据规范§4.4.4):
查看Nullable<T>
的源代码,没有特殊属性(期望[Serializable]
),那么编译器如何将其识别为“可空类型”?
回应以下评论:
int
是Int32
的别名:
(§4.1.4)简单类型通过保留字识别,但这些 对于预定义的结构类型,保留字只是别名 系统命名空间
T?
是Nullable<T>
的简写:
(§4.1.10) - 可空类型写为T ?,其中T是底层 类型。对于System.Nullable,这个语法是简写,两者 表格可以互换使用。
这似乎是一个明显的差异,下面没有反映出来。
那么编译器如何识别一个简单的结构(没有特殊代码)作为“可空类型”,结构名称?
答案 0 :(得分:2)
基于Shared Source CLI 2.0,Nullable<T>
通过PREDEFTYPEDEF
宏制作为“特殊”,其名称为“System.Nullable
”并将其映射到属性{ {1}}在整个编译器的其余部分进行检查。
关于PT_G_OPTIONAL
→int
等的别名,请参阅“好名字”栏。
来自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的目标受众群体,该版本是作为免费电子书发布的。