Nota
O acceso a esta páxina require autorización. Pode tentar iniciar sesión ou modificar os directorios.
O acceso a esta páxina require autorización. Pode tentar modificar os directorios.
Tip
¿Inicia un nuevo proyecto? Los nuevos proyectos creados a partir de .NET 6 o plantillas posteriores ya tienen <Nullable>enable</Nullable> establecido. No necesita una estrategia de migración: vaya a Resolución de advertencias que aceptan valores NULL.
¿Mantener un código base existente? Lea Tipos de referencia que aceptan valores NULL primero para comprender los contextos, las anotaciones y el estado de nulabilidad. En este artículo se da por supuesto que está familiarizado con esos conceptos y está listo para planear un lanzamiento.
Al activar tipos de referencia que aceptan valores NULL en un proyecto grande que se inició antes de que se introdujeran tipos de referencia que aceptan valores NULL, el compilador genera muchas advertencias a la vez. La migración consiste en secuenciar el trabajo: elegir un contexto predeterminado, exponer el archivo de advertencias por archivo o sección por sección y converger en <Nullable>enable</Nullable> todo el proyecto. La secuencia correcta depende de la actividad del código base y del riesgo que puede asumir en un solo paso.
El estado final es el mismo en cada caso: el proyecto establece <Nullable>enable</Nullable> y no contiene directivas #nullable de preprocesador.
Elegir un contexto predeterminado
El contexto que acepta valores NULL tiene dos marcas independientes: anotaciones (si ? declara un tipo de referencia que acepta valores NULL) y advertencias (si el compilador emite diagnósticos). Defínalos como un único valor <Nullable>:
| Valor predeterminado | Annotations | Advertencias | Más adecuado para |
|---|---|---|---|
disable
(implícito) |
desactivado | desactivado | Bibliotecas estables que no recibirán desarrollo de nuevas funcionalidades en esta fase. |
enable |
activado | activado | Código base activo con nuevos archivos frecuentes. El nuevo código empieza activado. |
warnings |
desactivado | activado | Migración en dos fases: primero aborde las advertencias; anote después. |
annotations |
activado | desactivado | Anote la API pública antes de corregir las advertencias internas. |
Elija la estrategia que mejor se adapte a los objetivos de la migración del proyecto:
- Desactivar como opción predeterminada. Establezca
<Nullable>disable</Nullable>y agregue#nullable enableen la parte superior de cada archivo a medida que lo migre. Los archivos existentes siguen siendo ajenos a la nulabilidad hasta que los modifiques. Esta opción presenta menos fricción para las bibliotecas estables, porque el desarrollo de nuevas funcionalidades es poco frecuente. - Habilite como valor predeterminado. Establezca
<Nullable>enable</Nullable>y agregue#nullable disableen la parte superior de cada archivo que aún no ha migrado. Cada archivo nuevo tiene en cuenta la nulabilidad desde el principio, por lo que el trabajo pendiente de migración no puede hacer más que reducirse. Esta opción es mejor cuando el desarrollo está activo. - Advertencias como valor predeterminado. Establezca
<Nullable>warnings</Nullable>. Elija esta opción predeterminada para una migración en dos fases: aborde las advertencias mientras cada tipo de referencia siga tratándose como no anotado y, a continuación, habilite las anotaciones. La división en dos fases mantiene acotadas las diferencias de cada paso. - Anotaciones como valor predeterminado. Establezca
<Nullable>annotations</Nullable>. Empiece anotando la API pública (?en los miembros que permitennull) antes de perseguir las advertencias. El compilador aún no emite advertencias, así que puedes definir la superficie de la API sin distracciones.
El archivo del proyecto controla el valor predeterminado global.
#nullable
Las directivas de preprocesador invalidan ese valor predeterminado para una región de código:
<PropertyGroup>
<Nullable>enable</Nullable>
</PropertyGroup>
Dentro de los archivos de origen, la directiva opta por una región dentro o fuera de la configuración que acepta valores NULL del proyecto:
#nullable disable
public static class LegacyHelper
{
// This file is nullable-oblivious. Reference types use the legacy rules.
public static string GetGreeting(string name) =>
name == null ? "hello" : $"hello {name}";
}
#nullable restore
#nullable enable
public static class MigratedHelper
{
// This file is fully migrated. Reference types are non-nullable by default.
public static string GetGreeting(string? name) =>
name is null ? "hello" : $"hello {name}";
}
#nullable restore
Migración de archivos por archivo
La manera más previsible de migrar un proyecto grande es activar las advertencias o las anotaciones archivo por archivo. El patrón es el mismo independientemente del valor predeterminado que elija:
- Elija un archivo. Comience con los tipos de hoja más profundos de su grafo de dependencias y, a continuación, avance hacia fuera. Anotar un tipo provoca nuevas advertencias en las funciones que lo llaman, por lo que trabajar de abajo arriba minimiza el retrabajo.
- Agregue la directiva
#nullableque hace que el archivo adopte el nuevo comportamiento. Use#nullable enablesi desea ambos indicadores. Use#nullable enable warningssolo para advertencias. - Solucione las advertencias del archivo mediante las técnicas de Resolución de advertencias que aceptan valores NULL.
- Repita el proceso con el siguiente archivo.
- Cuando todos los archivos del proyecto tienen su directiva, quite las directivas y establezca
<Nullable>enable</Nullable>en el nivel de proyecto.
Si tu base de código ya tiene <Nullable>enable</Nullable>, vas en la dirección opuesta. Suprima advertencias en archivos no migrados hasta que esté listo. Use #nullable disable para rechazar archivos y, a continuación, quite las supresiones de una en una.
Migración en dos fases
Una migración en dos fases separa los dos tipos de trabajo que implican los tipos de referencia anulables. Puede secuenciar las fases de cualquier manera, dependiendo de qué forma de estabilidad le importa más.
Primero, las advertencias y, a continuación, las anotaciones
Prioriza las advertencias cuando la prioridad sea corregir errores latentes System.NullReferenceException:
- Fase 1: Aborde las advertencias. Establezca el valor predeterminado del proyecto en
warnings. Los tipos de referencia siguen siendo ajenos a la nulabilidad, por lo que el sistema de tipos aún no cambia. El compilador emite advertencias en todas partes en las que el código existente puede que ya produzca una System.NullReferenceExceptionexcepción . Agregue comprobaciones de valores nulos, reestructure el flujo o aplique atributos hasta que el proyecto quede sin advertencias. Cada corrección hace que el código de producción sea más resistente incluso antes de que existan anotaciones. - Fase 2: Agregar anotaciones. Cambie el valor predeterminado del proyecto a
enable. Los tipos de referencia ahora no admiten valores NULL de forma predeterminada yvarlas variables locales se convierten en nullables. Las nuevas advertencias reflejan declaraciones que no coinciden con el modo en que se usan las variables. Añada?a los tipos que deberían permitirnull. Endurezca las API que deben requerir valores de entrada no nulos.
Anotaciones primero y luego advertencias
Prioriza las anotaciones cuando la estabilización de la superficie de la API pública sea la prioridad. Esta secuencia se adapta a las bibliotecas: puede enviar firmas anotadas para que los consumidores vean los contratos adecuados y cierren las advertencias internas según su propia programación.
- Fase 1: Agregar anotaciones. Establezca el valor predeterminado del proyecto en
annotations. Los tipos de referencia pasan a ser no anulables de forma predeterminada, pero el compilador no emite advertencias, por lo que el ruido no te molesta. Consulte la API pública y agregue?a todos los miembros que puedan devolver o aceptarnulllegítimamente . Refuerce las firmas que no deberían. Como las advertencias están desactivadas, puedes definir la estructura de la API en commits específicos sin tener que desenredar la implementación al mismo tiempo. - Fase 2: Abordar las advertencias. Cambie el valor predeterminado del proyecto a
enable. Las anotaciones que agregó en la fase 1 ahora alimentan el análisis de estado NULL, por lo que las advertencias que emite el compilador son de mayor calidad desde el principio: cada uno apunta al código cuyo comportamiento no coincide con el contrato que ya ha publicado. Resuélvalos con las técnicas de Resolución de advertencias de nulabilidad.
Elegir entre las ordenaciones
Cada ordenación separa las fases en diferencias más pequeñas y revisables. Una fase solo cambia el comportamiento y la otra solo cambia los tipos. La desventaja es que visita cada archivo dos veces. Para el código maduro y estable en el que cada cambio conlleva riesgos, los dos pasos suelen merecer la pena. Elija primero las advertencias cuando quiera proteger el código en ejecución. Elija primero las anotaciones si lo que más desea es publicar un contrato estable.
Se excluye el código generado
El compilador trata los archivos marcados como generados como si el contexto que acepta valores NULL estuviera deshabilitado, independientemente de la configuración del proyecto. Se considera que se genera un archivo cuando se cumple alguna de las condiciones siguientes:
- Una regla
.editorconfigestablecegenerated_code = truepara el archivo. - El primer comentario del archivo contiene
<auto-generated>o<auto-generated/>. - El nombre de archivo comienza por
TemporaryGeneratedFile_. - El nombre de archivo termina con
.designer.cs,.generated.cs,.g.cso.g.i.cs.
Los generadores que producen una salida compatible con valores NULL pueden volver a habilitarla emitiendo #nullable enable al principio del archivo generado.
Cuando hayas terminado
Una vez que cada archivo forma parte del proyecto predeterminado y se establece el elemento <Nullable>enable</Nullable>:
- Elimine todas las directivas
#nullablede su código fuente. - Quite los inicializadores
null!ydefault!que agregó solo para silenciar advertencias durante la migración. Reemplácelas por la inicialización adecuada o convierta el tipo en un tipo de referencia anulable. - Compruebe puntualmente la API pública. Todos los miembros que devuelven o aceptan
nulldeben anotarse con?. Las anotaciones forman parte del contrato una vez que el paquete se envía.
Ahora estás en la misma situación que los proyectos nuevos: los tipos de referencia anulables pasan a formar parte del sistema de tipos, y cualquier advertencia nueva refleja una discordancia real entre las declaraciones y el código. Use Resolver advertencias de valores NULL para solucionarlas a medida que surjan.