Tengo una clase simple como esta.
public class Greeting { public string From { get; set; } public string To { get; set; } public string Message { get; set; } }
Extrañamente recibo la siguiente advertencia.
Severity Code Description Project File Line Suppression State Warning CS8618 Non-nullable property 'From' must contain a non-null value when exiting constructor. Consider declaring the property as nullable. MxWork.Elsa2Wf.Tuts.BasicActivities D:\work\MxWork\Elsa2.0WfLearning\MxWork.Elsa2.0Wf.Tuts\src \MxWork.Elsa2Wf.Tuts.BasicActivities\Messages\Greeting.cs 5 Active
estoy desconcertado Este nuevo tipo de mensajes que lanza me quita la confianza. Los obtuve de las tres propiedades. Y esto ha aparecido de repente.
¿Puede alguien sugerir cómo se puede mitigar esto?
Estos días he visto usar por defecto! como tal, y su trabajo.
public class Greeting { public string From { get; set; } = default!; public string To { get; set; } = default!; public string Message { get; set; } = default!; }
También puede poner un signo de interrogación (?) para indicar que el tipo es anulable, si lo considera apropiado de la siguiente manera.
public class Greeting { public string? From { get; set; }; public string? To { get; set; }; public string? Message { get; set; }; }
El compilador le advierte que la asignación predeterminada de su propiedad de cadena (que es nula) no coincide con su tipo declarado (que es una string
no nula).
Esto se emite cuando los tipos de referencia anulables están activados, lo que cambia todos los tipos de referencia para que no sean nulos, a menos que se indique lo contrario con un ?
.
Por ejemplo, su código podría cambiarse a
public class Greeting { public string? From { get; set; } public string? To { get; set; } public string? Message { get; set; } }
para declarar las propiedades como cadenas anulables, o podría dar los valores predeterminados de las propiedades en línea o en el constructor:
public class Greeting { public string From { get; set; } = string.Empty; public string To { get; set; } = string.Empty; public string Message { get; set; } = string.Empty; }
si desea conservar los tipos de propiedades como no nulos.
Tener tipos de referencia anulables activados le ahorrará muchos dolores de cabeza cuando se trata de ejecutar su aplicación. El problema con muchas advertencias es que la mayoría puede no causar un problema, pero puede ocultar la que está causando un error difícil de encontrar.
Hay algunas trampas al usarlo como señala la pregunta y Slate y otros responden muy bien.
Es una muy buena idea tener una advertencia lo más cercana posible a cero.
Con nullable habilitado, produce muchas advertencias. Muchas veces el compilador simplemente sabe que algo podría ser nulo. Sin embargo, siendo más inteligente que el compilador, sabe que para cuando llegue a ese código, no será nulo.
Por ejemplo:
public partial class Exams: ComponentBase { [Inject] private IQuestionPoolFetchService? QPoolService { get; init; } private async Task FetchQuestionPool() { await QPoolService.GetAllQuestionsFromText(); }
Esto lanzará una advertencia CS8602. Porque tal vez de alguna manera el DI enviará un nulo. Por supuesto, sabemos que eso no va a suceder.
Podrías deshacerte de la advertencia con #prama como:
public partial class Exams: ComponentBase { [Inject] private IQuestionPoolFetchService? QPoolService { get; init; } private async Task FetchQuestionPool() { #pragma warning disables CS8602 // Dereference of a possibly null reference. await QPoolService.GetAllQuestionsFromText(); #pragma warning restore CS8602 // Dereference of a possibly null reference. }
Este es un código muy feo y empeora si tienes que repetirlo muchas veces.
Una mejor solución: usar el operador que perdona nulos. "!"
public partial class Exams: ComponentBase { [Inject] private IQuestionPoolFetchService? QPoolService { get; init; } private async Task FetchQuestionPool() { await QPoolService!.GetAllQuestionsFromText(); // null-forgiving ^ }
Esto le dice al compilador que oye, sé que esto podría ser nulo, pero no lo será.
Puede anotar una propiedad directamente como no anulable.
public string Property{ get; set; } = null!;
Y dará una advertencia si el usuario intenta establecer la Property
como null
También puede implementar un constructor para eliminar el error.
public class Greeting { public string From { get; set; } public string To { get; set; } public string Message { get; set; } public Greeting(string from, string to, string message) { From = from; To = to; Message = message; } }
Para Entity Framework trabajando con tipos de referencia anulables:
public class NullableReferenceTypesContext : DbContext { public DbSet<Customer> Customers => Set<Customer>(); public DbSet<Order> Orders => Set<Order>(); }