When compiling a C# application, we may see the warning “Non-nullable property must contain a non-null value when exiting constructor. Consider declaring it as nullable.” This article explains why we encounter this warning and what we can do to resolve it.
Without further ado, let’s get started!
Why Do We See This Warning?
Let’s consider a simple class:
public class Address { public string FirstName { get; set; } }
If we instantiate the Address
class, by default FirstName
will be null. The following code would then throw a System.NullReferenceException
:
var address = new Address(); int length = address.FirstName.Length;
This warning was added as part of the nullable reference types feature with C# 8. The feature aims to minimize the chances of our code throwing a NullReferenceException by analyzing the null-state of variables and warning when we may accidentally dereference a null. From .NET 6 onwards, this null-state analysis was enabled by default for new projects.
The feature is enabled via the <Nullable>enable</Nullable>
line in our .csproj
project file, so we can always enable it for existing projects by adding or editing this line.
Different Ways of Fixing This Warning
There are a number of ways we can address this warning:
- Initialize non-nullable properties
- Change the type to be nullable
- Disable the warning
- Use the null forgiving operator
- Use the required keyword
We should choose the option based on the specific context of our code.
Initialize All Non-nullable Properties
If we set sensible default values for our properties when the class is instantiated then this is a good way of avoiding dereferencing a null later in our code and therefore protects us from throwing a NullReferenceException
:
public class Address { public string FirstName { get; set; } = "Bob"; }
Alternatively, we can set the value of FirstName
through the constructor of the Address
class:
public Address() { FirstName = "Bob"; }
However, we may not be able to assign a suitable default value for all properties when we instantiate the Address
class. If this is the case, we should consider other ways of addressing the warning.
Change the Type to Be Nullable
If it is valid for the property to be null, we can make this explicit and change the type of the property to be nullable. For our example, we can change the type of our property from string
to string?
:
public class Address { public string? FirstName { get; set; } }
Now when we reference FirstName
elsewhere in our code, we can see that the type is nullable and therefore we will know to check for a null value.
Disable the Warning
We can stop the compiler from emitting these warnings by using preprocessor directives. In fact, we can disable any warning if we know the corresponding code:
public class Address { #pragma warning disable CS8618 public string FirstName { get; set; } #pragma warning restore CS8618 }
Alternatively, rather than disabling the specific warning, we can disable the nullable warning context for a specific section of code:
public class Address { #nullable disable public string FirstName { get; set; } #nullable restore }
If we want to disable all nullable warnings at the project level, we can add or set <Nullable>disable</Nullable>
in our .csproj
project file instead.
Use the Null Forgiving Operator
The null-forgiving operator !
suppresses all nullable warnings for the preceding expression:
public class Address { public string FirstName { get; set; } = null!; }
In our example, we suppress a nullable warning, yet FirstName
is still null and our code will still throw exceptions if we try and dereference FirstName
later in our code.
Use the required Keyword to Disable the Warning
From C# 11, we can use the required keyword to create the required members:
public class Address { public required string FirstName { get; set; }; }
By using the required
keyword, we disable the nullable warning but we have to initialize this property in the object initializer when creating the Address
object.
Conclusion
We’ve seen that the “Non-nullable property must contain a non-null value” warning is part of the improved static flow analysis that warns when we may try and dereference null. It is worth us understanding why the compiler is warning us and considering the options we have to address it. The safest option is to ensure we initialize all non-nullable properties with default non-null values. If that’s not possible or appropriate, we could change the type to nullable. Finally, if we are sure that we do not dereference a null elsewhere in our code, we could use the null forgiving operator or disable the warning entirely.