Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Los tipos de referencia que admiten un valor NULL permiten declarar si a las variables de un tipo de referencia se les debe asignar o no un valor null. El análisis estático y las advertencias del compilador cuando el código podría desreferenciar null son la ventaja más importante de esta característica. Una vez habilitado, el compilador genera advertencias que ayudan a evitar que se genere una excepción System.NullReferenceException cuando se ejecuta el código.
Si el código base es relativamente pequeño, puede activar la característica en el proyecto, resolver advertencias y disfrutar de las ventajas que ofrecen los diagnósticos mejorados. Las bases de código más grandes pueden requerir un enfoque más estructurado para resolver advertencias a lo largo del tiempo y habilitar la funcionalidad para algunos mientras resuelves advertencias en diferentes tipos o archivos. En este artículo se describen distintas estrategias para actualizar un código base y las contrapartidas asociadas a estas estrategias. Antes de iniciar la migración, lea la introducción conceptual de los tipos de referencia que admiten un valor NULL. En ella se trata el análisis estático del compilador, los valores null-state de maybe-null y not-null y las anotaciones que admiten un valor NULL. Una vez que se haya familiarizado con esos conceptos y términos, podrá migrar su código.
Planeación de la migración
Independientemente de cómo actualice su código base, el objetivo es que las advertencias y anotaciones que admiten un valor NULL estén habilitadas en su proyecto. Una vez que alcance ese objetivo, tendrá la configuración <nullable>Enable</nullable> en su proyecto. No necesitará ninguna de las directivas del preprocesador para ajustar la configuración en otro lugar.
Nota:
Puede designar una configuración de Nullable para el proyecto mediante una etiqueta <Nullable>. Consulte Opciones del compilador para obtener más información.
La primera opción es establecer el valor predeterminado para el proyecto. Las opciones son:
-
Nullable desactivado por defecto: disable es el valor predeterminado si no se añade un elemento
Nullablea su archivo de proyecto. Use este valor predeterminado cuando no esté agregando activamente nuevos archivos al código base. La actividad principal es actualizar la biblioteca para que utilice tipos de referencia que admiten un valor NULL. Si usas este valor predeterminado, se agrega una directiva de preprocesador nulificable a cada archivo a medida que actualizas tu código. -
Habilitar nulidad por defecto: Establezca este valor por defecto al desarrollar activamente nuevas funciones. Quiere que todo el código nuevo se beneficie de los tipos de referencia anulables y del análisis estático anulable. Si usa este valor predeterminado, deberá agregar un valor
#nullable disableen la parte superior de cada archivo. Eliminará estas directivas de preprocesador a medida que aborde las advertencias de cada archivo. -
Advertencias de nulabilidad como predeterminadas: Elija esta opción por defecto para una migración en dos fases. En la primera fase, aborde las advertencias. En la segunda fase, active las anotaciones para declarar el valor null-state que se espera de una variable. Si usa este valor predeterminado, deberá agregar un valor
#nullable disableen la parte superior de cada archivo. - Anotaciones de nulabilidad por defecto. Anote el código antes de resolver las advertencias.
Al habilitar una opción que admite un valor NULL como predeterminada, se genera más trabajo previo para agregar las directivas del preprocesador a cada archivo. La ventaja es que todos los archivos de código nuevos que se agreguen al proyecto estarán habilitados para aceptar valores NULL. Cualquier trabajo nuevo admitirá valores NULL; solo se debe actualizar el código existente. Deshabilitar 'nullable' como predeterminado funciona mejor si la biblioteca es estable, y el objetivo principal del desarrollo es adoptar tipos de referencia anulables. Los tipos de referencia anulables se activan al mismo tiempo que se anotan las API. Cuando haya terminado, habilite los tipos de referencia que aceptan valores NULL para todo el proyecto. Al crear un archivo nuevo, debe agregar las directivas del preprocesador y hacer que sea consciente de la anulabilidad. Si alguno de los desarrolladores de su equipo se olvida de hacerlo, ese nuevo código se sumará al trabajo pendiente para hacer que todo el código admita valores NULL.
La elección de una estrategia u otra dependerá de la cantidad de desarrollo activo que haya en el proyecto. Cuanto más desarrollado esté y más estable sea su proyecto, más adecuada será la segunda estrategia. Cuantas más características se estén desarrollando, más apropiada será la primera estrategia.
Importante
El contexto global que admite un valor NULL no se aplica a los archivos de código generado. En cualquier estrategia, el contexto que admite un valor NULL está deshabilitado para cualquier archivo de código fuente marcado como generado. Esto significa que las APIs de los archivos generados no están anotadas. Hay cuatro maneras de marcar un archivo como generado:
- En el archivo .editorconfig, especifique
generated_code = trueen una sección que se aplique a ese archivo. - Coloque
<auto-generated>o<auto-generated/>en un comentario en la parte superior del archivo. Puede estar en cualquier línea de ese comentario, pero el bloque de comentario debe ser el primer elemento del archivo. - Inicie el nombre de archivo con TemporaryGeneratedFile_
- Finalice el nombre de archivo con .designer.cs, .generated.cs, .g.cs o .g.i.cs.
Los generadores pueden optar por usar la directiva de preprocesador #nullable.
Comprende los contextos y las advertencias
Si se habilitan las advertencias y las anotaciones, se controlará cómo el compilador visualiza los tipos de referencia y la nulabilidad. Cada tipo tiene una de las tres nulabilidades:
- oblivious: todos los tipos de referencia son de tipo oblivious que admiten un valor NULL cuando el contexto de anotación de deshabilita.
-
nonnullable: tipo de referencia no anotado;
Ces nonnullable cuando el contexto de anotación se habilite. -
nullable: tipo de referencia anotado;
C?es de tipo nullable, pero puede que se genere una advertencia cuando el contexto de anotación se deshabilite. Las variables declaradas convarson de tipo nullable cuando el contexto de anotación se habilita.
El compilador genera advertencias en función de esa nulabilidad:
- Los tipos nonnullable generan advertencias si se les asigna un valor
nullpotencial. - Los tipos nullable generan advertencias si se desreferencian en el caso maybe-null.
- Los tipos oblivious generan advertencias si se desreferencian en el caso maybe-null y el contexto de advertencia está habilitado.
Cada variable tiene un estado predeterminado que admite un valor NULL que depende de su nulabilidad:
- Las variables que admiten un valor NULL tienen un estado predeterminado null-state de maybe-null.
- Las variables que no admiten un valor NULL tienen un estado predeterminado null-state de not-null.
- Las variables ignorantes que admiten valores nulos tienen un estado predeterminado null-state de not-null.
Antes de habilitar los tipos de referencia que aceptan valores NULL, todas las declaraciones del código base son de tipo nullable oblivious. Esto es importante porque significa que todos los tipos de referencia tienen un estado predeterminado null-state de not-null.
Resolución de advertencias
Si su proyecto usa Entity Framework Core, debe leer sus guías sobre cómo trabajar con tipos de referencia que admiten un valor NULL.
Al iniciar la migración, debe empezar habilitando solo las advertencias. Todas las declaraciones siguen siendo de tipo nullable oblivious, pero se le mostrarán advertencias cuando desreferencie un valor después de que su estado null-state cambie a maybe-null. A medida que resuelves estas advertencias, realizarás comprobaciones de null en más lugares, y tu código base será más resistente. Para obtener información sobre técnicas para situaciones específicas, vea el artículo sobre Técnicas para resolver advertencias nulas.
Puede resolver advertencias y habilitar anotaciones en cada archivo o clase antes de continuar con otro código. Sin embargo, a menudo resulta más eficaz resolver las advertencias generadas en el contexto indicado por warnings antes de habilitar las anotaciones de tipo. De esta forma, todos los tipos serán no conscientes hasta que haya resuelto el primer conjunto de advertencias.
Habilitar anotaciones de tipo
Después de resolver el primer conjunto de advertencias, podrá habilitar el contexto de anotación. Así, se cambiarán los tipos de referencia de oblivious a nonnullable. Todas las variables declaradas con var son de tipo nullable. Con este cambio se suelen generar nuevas advertencias. El primer paso para resolver las advertencias del compilador es usar anotaciones ? en los tipos de parámetros y de valores devueltos para indicar si los argumentos o los valores devueltos pueden ser null. A medida que realiza esta tarea, su objetivo no es solo corregir las advertencias. el objetivo más importante es hacer que el compilador entienda su intención de admitir posibles valores NULL.
Atributos extienden las anotaciones de tipo
Se han agregado varios atributos para expresar información adicional sobre el estado NULL de las variables. Es probable que las reglas de sus API sean más complicadas que not-null o maybe-null para todos los parámetros y valores devueltos. Muchas de las API tienen reglas más complejas para cuando las variables pueden ser null o no. En estos casos, usará atributos para expresar dichas reglas. Los atributos que describen la semántica de su API se encuentran en el artículo sobre los Atributos que afectan a los análisis que admiten un valor NULL.
Pasos siguientes
Una vez que haya resuelto todas las advertencias después de habilitar las anotaciones, podrá establecer el contexto predeterminado para su proyecto en enabled. Si ha agregado alguna pragma a su código para la anotación que admite un valor NULL o el contexto de advertencia, la podrá eliminar. Con el tiempo, es posible que se le muestren nuevas advertencias. Puede escribir código que introduzca advertencias. Una dependencia de biblioteca se puede actualizar para los tipos de referencia que aceptan valores NULL. Esas actualizaciones cambiarán los tipos de esa biblioteca de nullable oblivious a nonnullable o nullable.
También puede explorar estos conceptos en nuestro módulo de aprendizaje sobre Seguridad de nullabilidad en C#.