How does the compiler recognize Nullable <T> as a "special type"?
Nullable<T> is a structure that has the following definition:
public struct Nullable<T> where T : struct
where structis a type constraint, so T is bounded (according to the specification of §4.4.4):
- structure type or enumeration type
- not a type with a null value.
There Nullable<T>are no special attributes in the source text (expect for [Serializable]), since the compiler can recognize it as a "null type"?
In response to the comments below:
intis an alias for Int32:
(Section 4.1.4) simple types are identified using reserved words, but these reserved words are simply aliases for predefined structure types in the System Namespace
T?is an abbreviation for Nullable<T>:
(§4.1.10) - T?, T - . System.Nullable, .
, , .
, ( ) " ", ?
Common Source CLI 2.0, Nullable<T> "" PREDEFTYPEDEF, "System.Nullable" PT_G_OPTIONAL, .
int → System.Int32 ., . "nice name".
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:
/***************************************************************************************************
Return true iff the method is the nullable ctor taking one parameter.
***************************************************************************************************/
bool FUNCBREC::IsNubCtor(METHSYM * meth)
{
return meth && meth->getClass()->isPredefAgg(PT_G_OPTIONAL) && meth->params->size == 1 &&
meth->params->Item(0)->isTYVARSYM() && meth->isCtor();
}
, , , , CLI 2.0, .