Compartir vía


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 by A0 es el tipo subyacente de A si A es un tipo de valor anulable:

  1. Si A no existe o es un tipo de valor que no acepta valores NULL, se produce un error en tiempo de compilación.
  2. Si B no se puede convertir implícitamente en A o A0 (si A0 existe), se produce un error en tiempo de compilación.
  3. Si A0 existe y B se puede convertir implícitamente en A0y B no es dinámico, el tipo de a ??= b es A0. a ??= b se evalúa en tiempo de ejecución como:
    var tmp = a.GetValueOrDefault();
    if (!a.HasValue) { tmp = b; a = tmp; }
    tmp
    
    Excepto que a solo se evalúa una vez.
  4. De lo contrario, el tipo de a ??= b es A. a ??= b se evalúa en tiempo de ejecución como a ?? (a = b), excepto que a 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:

  1. 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:

  1. 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.