Это потому, что int?
на самом деле является сокращением Nullable<int>
. Вы можете сделать то же самое для своего типа:
MyStruct? a = null;
null
может быть неявно преобразовано только в тип , допускающий значение nullable , что означает любой ссылочный тип или любой тип значения, допускающий значение nullable, - где последний означает Nullable<T>
для некоторого T
.
Обратите внимание, что эта возможность конвертации из null
действительно язык функция - компилятор конвертирует это:
int? a = null;
в
int? a = new int?();
Они означают одно и то же - в основном «нулевое» значение для типа значения, допускающего значение NULL, - это значение, где HasValue
равно false, что будет по умолчанию. Это не то же самое, что нулевая ссылка - хотя добавление в ноль такого значения приведет к нулевой ссылке.
(Это один из примеров возможности, которая пересекает границы языка, библиотеки и CLR. Библиотечная часть довольно проста, часть CLR связана только с упаковкой и распаковкой - но есть довольно много с точки зрения поднятых операторов и т. Д. на языке.)