Prior to .NET 6, null-state analysis and variable annotations are disabled for existing project, however, it is enabled for all .NET 6 projects by default. Because of which, all the properties or models are showing warning for non-nullable elements.
Recent version of the Visual Studio 2022 and .NET 6, we have a common warning for the models or properties. The warning is given below.
Warning:
Non-nullable property must contain a non-null value when exiting constructor. Consider declaring the property as nullable
Recently, I was getting this warning for most of the properties which are not specified as nullable. I was not happy this warning though I was able run my .NET 6 application smoothly.
Exact Warning:
Non-nullable property ‘propertyname’ must contain a non-null value when exiting constructor. Consider declaring the property as nullable.
After carefully observing this error message, it makes sense for those properties. In order to minimize the likelihood that, our code causes the runtime to throw System.NullReferenceException, we need to resolve this warning.
Therefore, the compiler is giving warning in the solution that the default assignment of your properties (which is null) doesn’t match its state type (which is non-null string).
Let’s explore a bit more on nullable references.
Null state Analysis
This analysis highlights and tracks the null reference. In other words, our code may return null response, which may result in runtime error throwing System.NullReferenceException. The .NET compiler utilizes Null State Analysis to identify the null-state of a variable or properties.
To overcome this System.NullReferenceException and resolve this warning, we can assign a default value to the variable. Alternatively, we can check against null before doing any modification or operation.
Sample:
String rijsat = null;
//code
//code
// warning: dereference null.
Console.WriteLine($"The length of the message is {rijsat.Length}");
if(rijsat != null)
{
// No warning. Analysis determined "message" is not null.
Console.WriteLine($"The length of the message is { rijsat.Length}");
}
rijsat = "Hello, World!";
// No warning. Analysis determined "message" is not null.
Console.WriteLine($"The length of the message is {rijsat.Length}");
This is how static analysis determines that the rijsat
is dereference null, i.e. maybe-null. However, if we check null before using it or assign the value, then the warning will be removed.
Null variable Annotations
We generally define the variable to be either null or not null, explicitly with reference type.
We can declare a variable as non-nullable reference type or nullable reference type, which provides clear indication to null-state analysis. Based on the declaration, the compiler gets enough information to make assumptions about the variable.
Nullable Reference Type: we use syntax “?”
for nullable value types in variables. By appending ?
in the type of the variable, we declare a nullable variable.
Example
string? rijsat;
Using the above declaration, it is verified that all reference type variables in existing code. However, local variables var is considered as nullable.
We can also overwrite a warning if we know the variable is not null. Even though we know that value can’t be null, the compiler detects it as maybe-null with it null-state analysis. We can use null-forgiving operator ! after the variable. To overwrite compiler’s analysis:
Example
rijsat!.Length
Generally, the rules for handling any type of parameter as per C# 8.0.
- If the type argument for T is a reference type, T? references the corresponding nullable reference type. For example, if T is a string, then T? is a string?.
- If the type argument for T is a value type, T? references the same value type, T. For example, if T is an int, the T? is also an int.
- If the type argument for T is a nullable reference type, T? references that same nullable reference type. For example, if T is a string?, then T? is also a string?.
- If the type argument for T is a nullable value type, T? references that same nullable value type. For example, if T is a int?, then T? is also a int?.
https://docs.microsoft.com/en-us/dotnet/csharp/nullable-references
Solution
Now, we will discuss the solution for the above issue.
We can resolve this error in 3 ways.
Solution 1
We can simply make the properties nullable, as shown below:
Sample
public class AppSetting {
public string? ReferenceKey { get; set; }
public string? Value { get; set; }
public string? Description { get; set; }
}
Solution 2
We can assign default value to those properties as shown below:
public class AppSetting {
public string ReferenceKey { get; set; } = "Default Key";
public string Value { get; set; } = "Default Value";
public string Description { get; set; } = "Default Description";
}
Alternatively, you can give a reasonable default value for non-nullable strings as string.empty
.
Example
public class AppSetting {
public string ReferenceKey { get; set; } = string.empty;
public string Value { get; set; } = string.empty;
public string Description { get; set; } = string.empty;
}
Solution 3
You can disable this warning from project level. You can disable by removing the below line from project file csproj or setting.
<Nullable>enable</Nullable>
https://docs.microsoft.com/en-us/dotnet/csharp/nullable-references#nullable-contexts
These are three ways you can overcome the above warning.
Conclusion
In this article, we have elucidated about nullable references in C# in depth. In .NET 6, there is a common warning related to non-nullable property, and we discussed the reasons behind this. The compiler declares this warning in order to prevent exception throw related with System.NullReferenceException. Furthermore, I have shared various solutions to overcome and resolve the warning.