Назначение объединения null
Заметка
Эта статья является спецификацией компонентов. Спецификация служит проектным документом для функции. Она включает предлагаемые изменения спецификации, а также информацию, необходимую во время проектирования и разработки функции. Эти статьи публикуются до тех пор, пока предложенные изменения спецификации не будут завершены и включены в текущую спецификацию ECMA.
Может возникнуть некоторое несоответствие между спецификацией компонентов и завершенной реализацией. Эти различия отражены в соответствующих заметках собрания по проектированию языка (LDM).
Дополнительные сведения о процессе внедрения спецификаций функций в стандарт языка C# см. в статье о спецификациях .
Сводка
Упрощает распространенный шаблон кодирования, в котором переменная назначается значением, если оно равно NULL.
В рамках этого предложения мы также снимем ограничения типа в ??
, чтобы разрешить использование выражений с неограниченным типовым параметром на левой стороне.
Мотивация
Код в такой форме часто встречается.
if (variable == null)
{
variable = expression;
}
Это предложение добавляет в язык неперегружаемый двоичный оператор, который выполняет эту функцию.
Для этой функции было по крайней мере восемь отдельных запросов сообщества.
Подробный дизайн
Мы добавим новую форму оператора присваивания
assignment_operator
: '??='
;
Следует существующим семантическим правилам для составных операторов присваивания (§12.21.4), за исключением того, что мы пропускаем присваивание, если левая сторона не равна null. Ниже приведены правила для этой функции.
Учитывая a ??= b
, где A
является типом a
, B
является типом b
, и A0
является базовым типом A
, если A
является типом значения, допускающего значение NULL:
- Если
A
не существует или является типом значения, не допускающего значение NULL, возникает ошибка во время компиляции. - Если
B
не может быть неявно преобразован вA
илиA0
(еслиA0
существует), возникает ошибка компиляции. - Если
A0
существует иB
неявно преобразуется вA0
, аB
не является динамическим, то типa ??= b
A0
.a ??= b
оценивается во время выполнения следующим образом:
За исключением того, чтоvar tmp = a.GetValueOrDefault(); if (!a.HasValue) { tmp = b; a = tmp; } tmp
a
оценивается только один раз. - В противном случае тип
a ??= b
являетсяA
.a ??= b
оценивается в среде выполнения какa ?? (a = b)
, за исключением того, чтоa
оценивается только один раз.
Для снижения жесткости требований типа ??
мы вносим изменения в спецификацию, в которой сейчас указано, что при условии a ?? b
, где A
является типом a
:
- Если A существует и не является типом, допускаемым значением NULL или ссылочным типом, возникает ошибка во время компиляции.
Мы ослабляем это требование:
- Если A существует и является типом значения, не допускающего значение NULL, возникает ошибка во время компиляции.
Это позволяет оператору объединения null работать с параметрами без ограничений типа, так как параметр без ограничений типа T
существует, не является типом, допускающим значение NULL, и не является ссылочным типом.
Недостатки
Как и с любой языковой функцией, мы должны задаться вопросом, оправдана ли дополнительная сложность языка дополнительной ясностью, предлагаемой совокупности программ на C#, которые выигрывают от использования этой функции.
Альтернативы
Программист может писать (x = x ?? y)
, if (x == null) x = y;
или x ?? (x = y)
вручную.
Неразрешенные вопросы
- [ ] Следует ли также поддерживать операторы
&&=
и||=
?
Собрания по дизайну
Никакой.
C# feature specifications