Я пытаюсь понять систему ссылочных типов, допускающих значение NULL, в C# (ну, я думаю, ссылочные типы, допускающие значение NULL, являются уникальной частью). Механизм этой конкретной ситуации мне совершенно непонятен.
У меня есть метод
Код: Выделить всё
private static void ArrayModify(E?[] arr) where E : class { }
(Ограничение класса предназначено только для того, чтобы гарантировать, что значение null действительно может быть присвоено элементу массива в некотором гипотетическом коде.)
Если я напишу следующее:
Код: Выделить всё
string[] array = new string[3];
ArrayModify(array);
Я не получаю никаких предупреждений или ошибок. Для меня это не имеет смысла. Я понимаю, почему тип, не допускающий значения NULL, обычно может быть неявно преобразован в тип, допускающий значение NULL. Но возможность неявно привести A к B не означает, что вы можете неявно привести A[] к B[]. Конечно, ссылочные типы, допускающие значение NULL, на самом деле не реализованы таким образом, но в этом случае, если я присвою значение null элементу внутри функции, то в моем массиве предположительно строк, не допускающих значение NULL, у меня будет элемент null. Поэтому я бы не ожидал, что это сработает без какого-либо предупреждения.
Чтобы еще больше усложнить ситуацию, если мы изменим ArrayModify, чтобы он ожидал параметр ref:
Код: Выделить всё
private static void ArrayModify(ref E?[] arr) where E : class { }
Тогда напишите:
Код: Выделить всё
string[] array = new string[3];
ArrayModify(ref array);
Теперь я получаю предупреждение CS8620 («Аргумент не может быть использован для параметра из-за различий в допустимости значений NULL для ссылочных типов»), чего я и ожидал в первую очередь... но в чем разница??
Подробнее здесь:
https://stackoverflow.com/questions/798 ... -non-nulla