Asignación de uso combinado de NULL
Nota
Este artículo es una especificación de características. La especificación actúa como documento de diseño de la característica. Incluye cambios de especificación propuestos, junto con la información necesaria durante el diseño y el desarrollo de la característica. Estos artículos se publican hasta que se finalizan los cambios de especificación propuestos e se incorporan en la especificación ECMA actual.
Puede haber algunas discrepancias entre la especificación de características y la implementación completada. Esas diferencias se recogen en las notas de la reunión de diseño de lenguaje (LDM) correspondientes.
Puede obtener más información sobre el proceso de adopción de especificaciones de características en el estándar del lenguaje C# en el artículo sobre las especificaciones de .
Resumen
Simplifica un patrón de codificación común en el que se asigna un valor a una variable si es null.
Como parte de esta propuesta, también se suavizarán los requisitos de tipo en ??
para permitir que una expresión cuyo tipo sea un parámetro de tipo sin restricciones se use en el lado izquierdo.
Motivación
Es habitual ver el código del formulario.
if (variable == null)
{
variable = expression;
}
Esta propuesta agrega un operador binario no sobrecargable al lenguaje que realiza esta función.
Ha habido al menos ocho solicitudes de comunidad independientes para esta característica.
Diseño detallado
Agregamos una nueva forma de operador de asignación
assignment_operator
: '??='
;
Que sigue las reglas semánticas existentes para los operadores de asignación compuesta (§12.21.4), excepto que se omite la asignación si el lado izquierdo no es nulo. Las reglas de esta característica son las siguientes.
Dada a ??= b
, donde A
es el tipo de a
, B
es el tipo de b
y A0
es el tipo subyacente de A
si A
es un tipo de valor anulable:
- Si
A
no existe o es un tipo de valor que no acepta valores NULL, se produce un error en tiempo de compilación. - Si
B
no se puede convertir implícitamente enA
oA0
(siA0
existe), se produce un error en tiempo de compilación. - Si
A0
existe yB
se puede convertir implícitamente enA0
yB
no es dinámico, el tipo dea ??= b
esA0
.a ??= b
se evalúa en tiempo de ejecución como:
Excepto quevar tmp = a.GetValueOrDefault(); if (!a.HasValue) { tmp = b; a = tmp; } tmp
a
solo se evalúa una vez. - De lo contrario, el tipo de
a ??= b
esA
.a ??= b
se evalúa en tiempo de ejecución comoa ?? (a = b)
, excepto quea
solo se evalúa una vez.
Para relajar los requisitos de tipo de ??
, hemos actualizado la especificación donde actualmente se indica, dado a ?? b
, donde A
es el tipo de a
:
- Si A existe y no es un tipo que acepta valores NULL o un tipo de referencia, se produce un error en tiempo de compilación.
Relajamos este requisito para:
- Si A existe y es un tipo de valor que no acepta valores NULL, se produce un error en tiempo de compilación.
Esto permite que el operador de fusión null funcione en parámetros de tipo sin restricciones, ya que el parámetro de tipo sin restricciones T
existe, no es un tipo que acepta valores NULL y no es un tipo de referencia.
Inconvenientes
Al igual que con cualquier característica de lenguaje, debemos cuestionar si la complejidad adicional del lenguaje se devuelve en la claridad adicional que se ofrece al cuerpo de los programas de C# que se beneficiarían de la característica.
Alternativas
El programador puede escribir (x = x ?? y)
, if (x == null) x = y;
o x ?? (x = y)
a mano.
Preguntas sin resolver
- [ ] ¿También deberíamos admitir los operadores
&&=
y||=
?
Reuniones de diseño
Ninguno.
C# feature specifications