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 this, all the properties or models are showing warning for non-nullable elements. In this article, I will explore the warning with null reference in more detail and also provide the possible recommended solutions.
Recent version of Visual Studio 2022 and .NET 6, we have a common warning for the models or properties. The warning is given below.
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 with this warning though I was able to 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 are in the 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 its 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?.
For more detail Click here.
Now we will explore possible solutions.
Solution
Now, we will discuss the solution for the above warning. 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 it by removing the below line from project file csproj or setting.
<Nullable>enable</Nullable>
For more detail check this link.
Alternatively, you can go to project properties by right-clicking on it. Then make nullable enable from build general option as portrayed.
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.