This browser is no longer supported.

Upgrade to Microsoft Edge to take advantage of the latest features, security updates, and technical support.

Resolve nullable warnings

  • 5 contributors

This article covers the following compiler warnings:

  • CS8597 - Thrown value may be null.
  • CS8600 - Converting null literal or possible null value to non-nullable type.
  • CS8601 - Possible null reference assignment.
  • CS8602 - Dereference of a possibly null reference.
  • CS8603 - Possible null reference return.
  • CS8604 - Possible null reference argument for parameter.
  • CS8605 - Unboxing a possibly null value.
  • CS8607 - A possible null value may not be used for a type marked with [NotNull] or [DisallowNull]
  • CS8608 - Nullability of reference types in type doesn't match overridden member.
  • CS8609 - Nullability of reference types in return type doesn't match overridden member.
  • CS8610 - Nullability of reference types in type parameter doesn't match overridden member.
  • CS8611 - Nullability of reference types in type parameter doesn't match partial method declaration.
  • CS8612 - Nullability of reference types in type doesn't match implicitly implemented member.
  • CS8613 - Nullability of reference types in return type doesn't match implicitly implemented member.
  • CS8614 - Nullability of reference types in type of parameter doesn't match implicitly implemented member.
  • CS8615 - Nullability of reference types in type doesn't match implemented member.
  • CS8616 - Nullability of reference types in return type doesn't match implemented member.
  • CS8617 - Nullability of reference types in type of parameter doesn't match implemented member.
  • CS8618 - Non-nullable variable must contain a non-null value when exiting constructor. Consider declaring it as nullable.
  • CS8619 - Nullability of reference types in value doesn't match target type.
  • CS8620 - Argument cannot be used for parameter due to differences in the nullability of reference types.
  • CS8621 - Nullability of reference types in return type doesn't match the target delegate (possibly because of nullability attributes).
  • CS8622 - Nullability of reference types in type of parameter doesn't match the target delegate (possibly because of nullability attributes).
  • CS8624 - Argument cannot be used as an output due to differences in the nullability of reference types.
  • CS8625 - Cannot convert null literal to non-nullable reference type.
  • CS8629 - Nullable value type may be null.
  • CS8631 - The type cannot be used as type parameter in the generic type or method. Nullability of type argument doesn't match constraint type.
  • CS8633 - Nullability in constraints for type parameter of method doesn't match the constraints for type parameter of interface method. Consider using an explicit interface implementation instead.
  • CS8634 - The type cannot be used as type parameter in the generic type or method. Nullability of type argument doesn't match 'class' constraint.
  • CS8643 - Nullability of reference types in explicit interface specifier doesn't match interface implemented by the type.
  • CS8644 - Type does not implement interface member. Nullability of reference types in interface implemented by the base type doesn't match.
  • CS8645 - Member is already listed in the interface list on type with different nullability of reference types.
  • CS8655 - The switch expression does not handle some null inputs (it is not exhaustive).
  • CS8667 - Partial method declarations have inconsistent nullability in constraints for type parameter.
  • CS8670 - Object or collection initializer implicitly dereferences possibly null member.
  • CS8714 - The type cannot be used as type parameter in the generic type or method. Nullability of type argument doesn't match 'notnull' constraint.
  • CS8762 - Parameter must have a non-null value when exiting.
  • CS8763 - A method marked [DoesNotReturn] should not return.
  • CS8764 - Nullability of return type doesn't match overridden member (possibly because of nullability attributes).
  • CS8765 - Nullability of type of parameter doesn't match overridden member (possibly because of nullability attributes).
  • CS8766 - Nullability of reference types in return type of doesn't match implicitly implemented member (possibly because of nullability attributes).
  • CS8767 - Nullability of reference types in type of parameter of doesn't match implicitly implemented member (possibly because of nullability attributes).
  • CS8768 - Nullability of reference types in return type doesn't match implemented member (possibly because of nullability attributes).
  • CS8769 - Nullability of reference types in type of parameter doesn't match implemented member (possibly because of nullability attributes).
  • CS8770 - Method lacks [DoesNotReturn] annotation to match implemented or overridden member.
  • CS8774 - Member must have a non-null value when exiting.
  • CS8776 - Member cannot be used in this attribute.
  • CS8775 - Member must have a non-null value when exiting.
  • CS8777 - Parameter must have a non-null value when exiting.
  • CS8819 - Nullability of reference types in return type doesn't match partial method declaration.
  • CS8824 - Parameter must have a non-null value when exiting because parameter is non-null.
  • CS8825 - Return value must be non-null because parameter is non-null.
  • CS8847 - The switch expression does not handle some null inputs (it is not exhaustive). However, a pattern with a 'when' clause might successfully match this value.

The purpose of nullable warnings is to minimize the chance that your application throws a System.NullReferenceException when run. To achieve this goal, the compiler uses static analysis and issues warnings when your code has constructs that may lead to null reference exceptions. You provide the compiler with information for its static analysis by applying type annotations and attributes. These annotations and attributes describe the nullability of arguments, parameters, and members of your types. In this article, you'll learn different techniques to address the nullable warnings the compiler generates from its static analysis. The techniques described here are for general C# code. Learn to work with nullable reference types and Entity Framework core in Working with nullable reference types .

You'll address almost all warnings using one of four techniques:

  • Adding necessary null checks.
  • Adding ? or ! nullable annotations.
  • Adding attributes that describe null semantics.
  • Initializing variables correctly.

Possible dereference of null

This set of warnings alerts you that you're dereferencing a variable whose null-state is maybe-null . These warnings are:

The following code demonstrates one example of each of the preceding warnings:

In the example above, the warning is because the Container , c , may have a null value for the States property. Assigning new states to a collection that might be null causes the warning.

To remove these warnings, you need to add code to change that variable's null-state to not-null before dereferencing it. The collection initializer warning may be harder to spot. The compiler detects that the collection maybe-null when the initializer adds elements to it.

In many instances, you can fix these warnings by checking that a variable isn't null before dereferencing it. Consider the following that adds a null check before dereferencing the message parameter:

The following example initializes the backing storage for the States and removes the set accessor. Consumers of the class can modify the contents of the collection, and the storage for the collection is never null :

Other instances when you get these warnings may be false positive. You may have a private utility method that tests for null. The compiler doesn't know that the method provides a null check. Consider the following example that uses a private utility method, IsNotNull :

The compiler warns that you may be dereferencing null when you write the property message.Length because its static analysis determines that message may be null . You may know that IsNotNull provides a null check, and when it returns true , the null-state of message should be not-null . You must tell the compiler those facts. One way is to use the null forgiving operator, ! . You can change the WriteLine statement to match the following code:

The null forgiving operator makes the expression not-null even if it was maybe-null without the ! applied. In this example, a better solution is to add an attribute to the signature of IsNotNull :

The System.Diagnostics.CodeAnalysis.NotNullWhenAttribute informs the compiler that the argument used for the obj parameter is not-null when the method returns true . When the method returns false , the argument has the same null-state it had before the method was called.

There's a rich set of attributes you can use to describe how your methods and properties affect null-state . You can learn about them in the language reference article on Nullable static analysis attributes .

Fixing a warning for dereferencing a maybe-null variable involves one of three techniques:

  • Add a missing null check.
  • Add null analysis attributes on APIs to affect the compiler's null-state static analysis. These attributes inform the compiler when a return value or argument should be maybe-null or not-null after calling the method.
  • Apply the null forgiving operator ! to the expression to force the state to not-null .

Possible null assigned to a nonnullable reference

This set of warnings alerts you that you're assigning a variable whose type is nonnullable to an expression whose null-state is maybe-null . These warnings are:

The compiler emits these warnings when you attempt to assign an expression that is maybe-null to a variable that is nonnullable. For example:

The different warnings indicate provide details about the code, such as assignment, unboxing assignment, return statements, arguments to methods, and throw expressions.

You can take one of three actions to address these warnings. One is to add the ? annotation to make the variable a nullable reference type. That change may cause other warnings. Changing a variable from a non-nullable reference to a nullable reference changes its default null-state from not-null to maybe-null . The compiler's static analysis may find instances where you dereference a variable that is maybe-null .

The other actions instruct the compiler that the right-hand-side of the assignment is not-null . The expression on the right-hand-side could be null-checked before assignment, as shown in the following example:

The previous examples demonstrate assignment of the return value of a method. You may annotate the method (or property) to indicate when a method returns a not-null value. The System.Diagnostics.CodeAnalysis.NotNullIfNotNullAttribute often specifies that a return value is not-null when an input argument is not-null . Another alternative is to add the null forgiving operator, ! to the right-hand side:

Fixing a warning for assigning a maybe-null expression to a not-null variable involves one of four techniques:

  • Change the left side of the assignment to a nullable type. This action may introduce new warnings when you dereference that variable.
  • Provide a null-check before the assignment.
  • Annotate the API that produces the right-hand side of the assignment.
  • Add the null forgiving operator to the right-hand side of the assignment.

Nonnullable reference not initialized

This set of warnings alerts you that you're assigning a variable whose type is non-nullable to an expression whose null-state is maybe-null . These warnings are:

Consider the following class as an example:

Neither FirstName nor LastName are guaranteed initialized. If this code is new, consider changing the public interface. The above example could be updated as follows:

If you require creating a Person object before setting the name, you can initialize the properties using a default non-null value:

Another alternative may be to change those members to nullable reference types. The Person class could be defined as follows if null should be allowed for the name:

Existing code may require other changes to inform the compiler about the null semantics for those members. You may have created multiple constructors, and your class may have a private helper method that initializes one or more members. You can move the initialization code into a single constructor and ensure all constructors call the one with the common initialization code. Or, you can use the System.Diagnostics.CodeAnalysis.MemberNotNullAttribute and System.Diagnostics.CodeAnalysis.MemberNotNullWhenAttribute attributes. These attributes inform the compiler that a member is not-null after the method has been called. The following code shows an example of each. The Person class uses a common constructor called by all other constructors. The Student class has a helper method annotated with the System.Diagnostics.CodeAnalysis.MemberNotNullAttribute attribute:

Finally, you can use the null forgiving operator to indicate that a member is initialized in other code. For another example, consider the following classes representing an Entity Framework Core model:

The DbSet property is initialized to null! . That tells the compiler that the property is set to a not-null value. In fact, the base DbContext performs the initialization of the set. The compiler's static analysis doesn't pick that up. For more information on working with nullable reference types and Entity Framework Core, see the article on Working with Nullable Reference Types in EF Core .

Fixing a warning for not initializing a nonnullable member involves one of four techniques:

  • Change the constructors or field initializers to ensure all nonnullable members are initialized.
  • Change one or more members to be nullable types.
  • Annotate any helper methods to indicate which members are assigned.
  • Add an initializer to null! to indicate that the member is initialized in other code.

Mismatch in nullability declaration

Many warnings indicate nullability mismatches between signatures for methods, delegates, or type parameters.

The following code demonstrates CS8764 :

The preceding example shows a virtual method in a base class and an override with different nullability. The base class returns a non-nullable string, but the derived class returns a nullable string. If the string and string? are reversed, it would be allowed because the derived class is more restrictive. Similarly, parameter declarations should match. Parameters in the override method can allow null even when the base class doesn't.

Other situations can generate these warnings. You may have a mismatch in an interface method declaration and the implementation of that method. Or a delegate type and the expression for that delegate may differ. A type parameter and the type argument may differ in nullability.

To fix these warnings, update the appropriate declaration.

Code doesn't match attribute declaration

The preceding sections have discussed how you can use Attributes for nullable static analysis to inform the compiler about the null semantics of your code. The compiler warns you if the code doesn't adhere to the promises of that attribute:

Consider the following method:

The compiler produces a warning because the message parameter is assigned null and the method returns true . The NotNullWhen attribute indicates that shouldn't happen.

To address these warnings, update your code so it matches the expectations of the attributes you've applied. You may change the attributes, or the algorithm.

Exhaustive switch expression

Switch expressions must be exhaustive , meaning that all input values must be handled. Even for non-nullable reference types, the null value must be accounted for. The compiler issues warnings when the null value isn't handled:

The following example code demonstrates this condition:

The input expression is a string , not a string? . The compiler still generates this warning. The { } pattern handles all non-null values, but doesn't match null . To address these errors, you can either add an explicit null case, or replace the { } with the _ (discard) pattern. The discard pattern matches null as well as any other value.

Coming soon: Throughout 2024 we will be phasing out GitHub Issues as the feedback mechanism for content and replacing it with a new feedback system. For more information see: https://aka.ms/ContentUserFeedback .

Submit and view feedback for

Additional resources

The Code Blogger

Approaches for Resolving Nullable Warnings on Existing Codebase

  • Post author: Manoj Choudhari
  • Post published: May 31, 2022
  • Post category: .NET
  • Post comments: 2 Comments

In the previous article , we have discussed basic concepts about what nullable reference types means and how this feature can be enabled.

As you may already know, this feature is by default enabled on the new projects created using .NET 6. That’s why if you have an existing codebase and if you want to upgrade it to .NET 6, it may be a good idea to enable this feature now on the existing projects.

When you enable this new feature on existing codebase, the compiler may start emitting a lot of warnings. This article is a conceptual guide, that will help understanding what should be the approach in fixing those warnings.

Prerequisites

This article is kind of conceptual guide for enabling the nullable reference types in an existing codebase and resolving the nullable warnings. So, the only pre-requisite is, the codebase should already have been using C# 8 or later version – because nullable reference types was not supported on previous versions of C#.

Overview – Fixing Nullable Warnings

As stated in the previous post, this feature, nullable reference types, can be enabled either in the source code files by using #nullable or by enabling appropriate settings in the project files. Once this feature is enabled, compiler will start performing some code analysis.

Based on this analysis, the compiler will emit the warnings wherever the code has used constructs which may lead to NullReferenceException . Resolving those warnings is really tricky. Some warnings may seem easy to resolve, but they may generate new warnings.

We can address all the warnings by using one of the four techniques:

  • Adding appropriate null checks – e.g. either an exception can be thrown or some default values can be initialized.
  • ‘?’ posfixed to the type name at declaration, to make the variable nullable
  • ‘!’ posfixed to the variables so as to convey compiler that the value would not be null
  • Adding attributes that describe the null semantics
  • Initializing the variables correctly

Now, let’s have a look at some common nullable warnings. We will discuss what that warning is about and how to resolve the warning.

Warning: Possible NULL Reference Return

This warning suggests that the return type of method is non-nullable, while the method is returning null. You will get this warning at almost all the places where method is returning null.

This error is because the reference type was nullable by default, but because enabling nullable reference types, the type is non-nullable now.

In order to fix this warning, the return type should be marked as nullable.

Warning: Possible NULL Assignment to Non-Nullable Type Variable

After we enable the nullable reference types feature, all the reference types by default become non-nullable. Only one exception – the variables declared with var keyword are considered to be nullable.

In the GetMessage method shown in the above snapshot, before enabling the null reference types (NRT), the code was working perfectly fine. But after enabling the NRT, the method can return null, that’s why we had to make the return type of the method to be nullable string, by appending the ‘?’ to the return type.

It resolves the nullable reference type warning as explained in previous section. But also, it introduces new warning – the result of method call now can be nullable, but the data type of the variable suggests that the data type of message variable is not null.

There are three alternatives to fix this warning:

  • Change the left side of assignment and make the type nullable. This action may introduce new warnings
  • Provide null check before assignment
  • Annotate the API on right hand side to convey that return type is not null
  • Add null-forgiving operator ( ‘!’ ) to the right hand side of assignment

All these 3 fixes are shown in the code snippet given below. The fourth fix we will discuss later in some other post, when we discuss about attributes that can be placed on methods and method parameters.

Warning: Dereference of Possibly a NULL reference

Whenever we choose to make make the variable type nullable by appending the ‘?’ operator to the type name while declaring variable, this new warning may get introduced.

This warning suggests that a variable that is being accessed, may be null. There are three resolutions to this warning:

  • Add a null check and execute the path only if the variable is not null
  • Add a null forgiving operator
  • Another option is to add appropriate null-state analysis attributes on the APIs that is causing this warning.

The code example given below provides examples of first two resolutions from the above mentioned list:

Sometimes, this warning may be a false positive. Let’s say you already checked for null in a private method, named IsValid .

There is no way for compiler to know that this IsValid method provides null check. So, for such cases, we can use attributes to decorate the parameters to convey that the parameter would not be null if certain condition is met. Or alternatively, null-forgiving operator can also be used here.

Warning: Non-Nullable Reference Not Initialized

This warning is for all the variables (of reference types, obviously) which were declared, but were not initialized. This warning is common if you have POCO classes which contain only read-write properties. It can also be applicable for fields or local variables which are not initialized.

Especially while calling Try**** methods, generally they need an out parameter. In those cases, many times, we might have declared variable just before that call, which may not have been initialized.

In order to fix this warning, there are four alternatives:

  • Add (or modify existing) constructors or field / property initializers to ensure non-nullable members are initialized
  • Check if the non-nullable properties are really supposed to be non-nullable. If they are part of optional data, you can change them to nullable.
  • if there are any helper methods, we can annotated those methods with appropriate attributes
  • Initialize the value to null! to indicate that the non-nullable field is getting initialized in some other parts of code.

Below code snippet shows couple of examples which may generate this warning and their fixes.

Warning: Nullability Mismatch

This warning appears only in case the class is getting derived from other class or if the class is implementing interface(s). The warning says that the signatures of the methods are not matching. The nullability of return types and/or parameters in method signature is not matching to delegates / interface definition / base class.

Warning: Code Does Not Match Attribute Declaration

As I mentioned earlier, we can apply some annotations on methods to guide the compiler’s null analysis. But if compiler figures out that the annotations are not matching with the code outcome, then this kind of warning is emitted.

There are very less chances that you would see this warning while enabling nullable reference types in an existing codebase. In fact, you will not see this warning as long as you do not use annotations on APIs (attributes on methods).

The code snippet given below shows an example of such occurrence. Here, the attribute is suggesting that out parameter is not null when returned value is true. But in the code, out parameter is getting set to null even when method returns true. That’s why compiler would produce the warning.

In this case the only resolution is to either modify the code or modify the annotations so that expectations set by annotations match with the code.

Verifications and Testing

If your solution is complex, I would suggest to go project by project. It means that we should select a project, enable nullable reference types feature and then resolve all the warnings for that project. Then select another project.

Also, while migrating to adopt this feature, it is immensely important not to apply any unrelated refactoring. I will try to share some tips and tricks in the coming post that would enable you to decide your path for this migration and it will also give you some idea about how to estimate that activity.

Nullable reference feature does not change run-time behavior. It is just a compile time feature, compiler can analyze the code and can warn developers wherever it thinks null reference exception can occur.

So, for verifications, there is no special efforts required. We can just run existing automated tests to ensure that code works as expected. As long as tests are green, you should be good to merge the code.

What should I do after all warnings are fixed / verified ?

This section is applicable only if you migrated existing codebase to adopt this new feature. The codebase may have a lot of business functionality already developed before adopting this feature, and hence, during the migrations, it may not be possible to discuss every entity in detail to decide its nullability.

So, cutting long story short, deciding on nullability is crucial here and it may be tricky to figure out appropriate nullability if you are working on complex / huge code base.

Some tips that you can use while deciding whether a property or field should be nullable or not are:

  • you can check the database design if the field maps to database to understand if field should be nullable.
  • You can check if field (or its corresponding fields) is marked as required in some other layers. If it is required, then mostly it should be non-nullable.
  • Otherwise, we can check the related methods to see how the objects of the concerned types are getting used. Based on the usage, you should be able to infer, most probable nullability that you should assign to the property / field / variables.
  • You can also discuss with team / product owner wherever you have queries to ensure that your analysis is matching the overall understanding of the solution.

So, because this activity is tricky, there are chances that you may have missed few things. Or it may also happen that you applied correct nullability but the feature requirements got changed. So, there are two things that we should keep an eye on :

  • IF any design / requirement change would affect existing nullability. If it is affecting, then related fields / properties / variables should be changed appropriately.
  • If any thing was missed as a part of initial migration, then when any related work is going on, team should always keep their eyes open to catch such issues and prioritize those fixes as per discussions with team.
  • Enable warnings as errors for Nullable warnings ( how to part is mentioned in my previous article ).

I hope you find this article helpful. Let me know your thoughts.

Share this article on:

Please share this share this content.

  • Opens in a new window

You Might Also Like

Read more about the article Dependency Injection In .NET – Default Container vs Autofac

Dependency Injection In .NET – Default Container vs Autofac

API - Feature Flags - App Configuration Service

App Configuration – Using the feature flags from ASP .NET Core API

.NET Core Web API - XML and Newtonsoft Formatters

XML and NewtonsoftJSON formatters for .NET Core Web APIs

Leave a reply cancel reply, this post has 2 comments.

possible null assignment to non nullable entity

Thank for the article, it’s a huge help

possible null assignment to non nullable entity

Glad to know it helped ! Thanks !

Discover more from The Code Blogger

Subscribe now to keep reading and get access to the full archive.

Type your email…

{{#message}}{{{message}}}{{/message}}{{^message}}Your submission failed. The server responded with {{status_text}} (code {{status_code}}). Please contact the developer of this form processor to improve this message. Learn More {{/message}}

{{#message}}{{{message}}}{{/message}}{{^message}}It appears your submission was successful. Even though the server responded OK, it is possible the submission was not processed. Please contact the developer of this form processor to improve this message. Learn More {{/message}}

Submitting…

Continue reading

  • Sep 30, 2019

Exploring the non-nullable type warnings in C# 8

possible null assignment to non nullable entity

C# 8 will bring us many new exciting features, and personally my favorite feature is the non-nullable type one.

If you are new to this feature, then I recommend you first read up on it here:

Nullable reference types in C#

Try out Nullable Reference Types

When I researched this new feature online, I found that most of the examples looked something like this: (This code will result in the following two null-warnings)

This is of course cool, but what other warnings can be generated by the Roslyn compiler? To what extent can the compiler detect null-warnings? In this blog post, I want to explore as many of the null-related warnings as possible.

So, to get a better feeling for what is actually possible, let’s find out!

Where to find all the possible compiler warnings?

The first step is to look at all the related null-warnings that exists, and from that get a better clue for what is possible.

During my research I found that the Roslyn compiler source-code itself is the best source for this information. The source-code for the compiler is hosted on GitHub here. In the source-code I located the ErrorCode enum located here . It contains a big enum of all the possible error codes, and conveniently the null related warnings I found were located in the range between 8597 -> 8715.

An example from this enum is:

The warning strings

This is a great start, but having the warning name and number is not so helpful. I want to see the actual warning strings, so where can I find them?

It turns out that I can, for a given warning above, based on the enum name, lookup the corresponding warning message string in the file CSharpResources.resx , located here. As an example, for the warning WRN_NullReferenceReturn , the corresponding warning string is:

Cool! I have located all the null related warnings messages in the compiler source code, but now the question is how can I write C# 8 code, to trigger most of these warnings?

The warnings

The warnings that I have created test code for are the following:

Exceptions CS8597 Thrown value may be null.

Partial classes CS8611 Nullability of reference types in type of parameter 'XXX' doesn't match partial method declaration.

Delegates CS8621 Nullability of reference types in return type of 'XXX' doesn't match the target delegate 'YYY'. CS8622 Nullability of reference types in type of parameter 'XXX' of 'YYY' doesn't match the target delegate 'ZZZ'.

Inheritance CS8609 Nullability of reference types in return type doesn't match overridden member. CS8610 Nullability of reference types in type of parameter 'XXX' doesn't match overridden member.

Interface CS8613 Nullability of reference types in return type of 'XXXX' doesn't match implicitly implemented member 'YYY'. CS8614 Nullability of reference types in type of parameter 'XX' of 'YYY' doesn't match implicitly implemented member 'ZZZ'. CS8616 Nullability of reference types in return type doesn't match implemented member 'XXX'. CS8617 Nullability of reference types in type of parameter 'XXX' doesn't match implemented member 'YYY'.

Field and properties CS8618 Non-nullable property 'XXX' is uninitialized. CS8618 Non-nullable field 'XXX' is uninitialized.

Methods calls CS8603 Possible null reference return. CS8604 Possible null reference argument for parameter 'XXXX' in 'YYYY'. CS8620 Argument of type 'XXX' cannot be used for parameter 'YYY' of type 'ZZZ' in 'AAA' due to differences in the nullability of reference types. CS8624 Argument of type 'XXX' cannot be used as an output of type 'YYY' for parameter 'ZZZ' in 'AAA' due to differences in the nullability of reference types.

Assignments CS8600 Converting null literal or possible null value to non-nullable type. CS8601 Possible null reference assignment. CS8602 Dereference of a possibly null reference. CS8605 Unboxing a possibly null value. CS8606 Possible null reference assignment to iteration variable CS8619 Nullability of reference types in value of type 'XXX' doesn't match target type 'YYY'. CS8625 Cannot convert null literal to non-nullable reference type. CS8629 Nullable value type may be null.

Generics CS8631 The type '{3}' cannot be used as type parameter '{2}' in the generic type or method '{0}'. Nullability of type argument '{3}' doesn't match constraint type '{1}'.</value> CS8634 The type cannot be used as type parameter in the generic type or method. Nullability of type argument doesn't match 'class' constraint.

The majority of the non-nullable type issues are represented as warnings, there are also a few that are treated as compiler errors, and I decided to ignore those because I want my code to actually compile.

The Source code

The source code for the project that will trigger all the warnings above can be found on GitHub here.

Conclusions

It’s really impressive how many warnings related to null that the compiler can generate, and I assume this list will grow over time as the compiler and this feature evolves.

Feedback wanted

Have you found some code that does cover a null related warning that is not yet covered? Then contact me at [email protected] or send me a pull request!

About the author

Tore has worked with everything from low-level programming in assembler to building event-driven applications with the CQRS architecture. Everyday, he works to educate developers where he likes to share his experiences from his various projects. As a person, Tore is constantly curious about new technologies and his motto "One can not say anything until one can explain it to others" is his guiding star. Do Want to learn more about C# and .NET core? Then explore the training offering by Edument, we have training classes all the way from beginning to advanced C#/.NET. See our courses in .NET.

Recent Posts

Docker tip: Set build-time arguments for cache busting

React 18: Improved data fetching using the new startTransition API

Codebase got you frustrated? You are not alone!

Code Maze

  • Blazor WASM 🔥
  • ASP.NET Core Series
  • GraphQL ASP.NET Core
  • ASP.NET Core MVC Series
  • Testing ASP.NET Core Applications
  • EF Core Series
  • HttpClient with ASP.NET Core
  • Azure with ASP.NET Core
  • ASP.NET Core Identity Series
  • IdentityServer4, OAuth, OIDC Series
  • Angular with ASP.NET Core Identity
  • Blazor WebAssembly
  • .NET Collections
  • SOLID Principles in C#
  • ASP.NET Core Web API Best Practices
  • Top REST API Best Practices
  • Angular Development Best Practices
  • 10 Things You Should Avoid in Your ASP.NET Core Controllers
  • C# Back to Basics
  • C# Intermediate
  • Design Patterns in C#
  • Sorting Algorithms in C#
  • Docker Series
  • Angular Series
  • Angular Material Series
  • HTTP Series
  • .NET/C# Author
  • .NET/C# Editor
  • Our Editors
  • Leave Us a Review
  • Code Maze Reviews

Select Page

How to Resolve Non-nullable Property Must Contain a Non-null Value Warning

Posted by Code Maze | Updated Date Jan 20, 2023 | 2

How to Resolve Non-nullable Property Must Contain a Non-null Value Warning

Want to build great APIs? Or become even better at it? Check our Ultimate ASP.NET Core Web API program and learn how to create a full production-ready ASP.NET Core API using only the latest .NET technologies. Bonus materials (Security book, Docker book, and other bonus files) are included in the Premium package!

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:

Become a patron at Patreon!

If we instantiate the Address class, by default FirstName will be null. The following code would then throw a System.NullReferenceException :

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 :

Alternatively, we can set the value of FirstName through the constructor of the Address class:

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? :

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:

Alternatively, rather than disabling the specific warning, we can disable the nullable warning context for a specific section of code:

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:

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:

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.

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.

guest

You forgot the required keyword. That will fix it!

Marinko Spasojević

Thank you, David. You are correct, that will fix the warning too. We’ll update the article.

wpdiscuz

Join our 20k+ community of experts and learn about our Top 16 Web API Best Practices .

Throughout this chapter, we have consistently disabled the C# nullable warning:

CS8618: Non-nullable field/property is uninitialized. Consider

declaring as nullable.

When you declare reference type (1) non-nullable fields or (2) non-nullable automatically implemented properties, it is obvious that these fields and properties need to be initialized before the containing object is fully instantiated. Not doing so would leave those fields and properties with a default null value—so they shouldn’t be declared as non-nullable.

The problem is that frequently the non-nullable fields and properties are initialized indirectly, outside the immediate scope of the constructor and therefore beyond the scope of the compiler’s code analysis, even if they are still, in fact, initialized, perhaps via a method or property that the constructor invokes. 10 Following are some examples of this practice:

In most cases, the reference type non-nullable field or non-nullable automatically implemented property (referred to as a non-nullable field/property in this section—“reference type” is implied) is assigned indirectly via properties or methods that the constructor invokes. Unfortunately, the C# compiler doesn’t recognize an indirect assignment of a non-nullable field/property.

Furthermore, all non-nullable fields/properties need to ensure that they are not assigned a value of null . In the case of fields, they need to be wrapped in properties with the setter validation ensuring that a null value will not be assigned. (Remember that field validation relies on the guideline that we do not access fields outside of the property that wraps them.) The result is that non-nullable read-write fully implemented reference type properties should have validation preventing null assignment.

Non-nullable automatically implemented properties need to be limited to read-only encapsulation, with any values assigned during instantiation and validated as not null prior to assignment. Read-write non-nullable reference type automatically implemented properties should be avoided, especially with public setters, since preventing null assignment is problematic. Although the uninitialized non- null property compiler warning can be avoided by assigning the property from the constructor, this is not enough: The property is read-write, so it could be assigned null after instantiation, thereby voiding your intent for it to be non-nullable.

Listing 6.36 demonstrates how to inform the compiler and avoid the false warning that a non-nullable field/property is uninitialized. The end goal is to allow the programmer to inform the compiler that the properties/fields are non-nullable so that the compiler can inform callers about the (non-)nullability of those properties/fields.

The code snippet to handle non-nullable properties/fields that are not directly initialized by the constructor has several important qualities (listed in no particular order here):

For a non-nullable property, it is seemingly nonsensical to declare the backing field as nullable. This is necessary, however, since the compiler is oblivious to non-nullable field/property assignments outside from the constructor. Fortunately, this is a case where you, as the programmer, are justified in using the null-forgiveness operator when returning the field because of the not- null check in the setter that ensures the field is never null .

As pointed out earlier in this section, non-nullable automatically implemented reference-type properties need to be read-only to avoid invalid null assignments. However, you still need to validate any parameters that may be assigned during instantiation, as shown in Listing 6.37 .

One could debate whether a private setter should be allowed on non-nullable automatically implemented reference-type properties. While possible, the more appropriate question to ask is whether your class could mistakenly assign null to the property. If you don’t encapsulate the field with validation in a setter, can you be sure you won’t mistakenly assign a null value? While the compiler will verify your intent during instantiation, it is questionable that the developer will always remember to check for null in values coming into your class that should be non-nullable—as occurs in the constructor shown in Listing 6.37 .

In C# 11, the designers add the ability to mark either a field or a property as required. This designates them as “required” such that they must be assigned inside the object initializer during construction (see Listing 6.38 ).

By adding the required modifier, we can no longer instantiate a book without supplying an object initializer that provides value for both the Isbn number and the Title (see Listing 6.39 ).

Notice that since we don’t include an explicit constructor for Book , we rely on the automatically generated default constructor to instantiate the book. This is ideal since the required members define how to construct the object in place of any constructor. Providing a constructor with parameters for the required members will result in having to specify the values both as constructor arguments and, redundantly, in the object initializer. A constructor with a Title parameter, for example, will result in an instantiation like this:

Book book = new ( "A People’s History of the United States" )

   Title= "A People’s History of the United States" ,

  Isbn= "978-0062397348"

To avoid this redundancy, you can decorate a constructor with the SetRequireParameters attribute, instructing the compiler to disable all the object initializer requirements when invoking the associated constructor. (Effectively, the SetRequireParameters attribute instructs the compiler that the developer will take care of setting all the required members so the compiler can ignore checking for initialization assignment. Unfortunately, however, there is little to no verification that such initialization did occur—the compiler doesn’t check. See Listing 6.40 for an example of how to use the SetsRequiredMembers attribute.

And, given such a constructor, we can instantiate a book without setting any required members:

Book book = new(42) {

     Subtitle = "The Comprehensive, Expert Guide " +

         "to C# for Programmers at All Levels" };

The disadvantage, of course, it this assumes that the constructor has valid values to assign the required members. There is no point in telling the compiler to ignore the required members if in fact there are no available ways to determine the valid required member values. Doing so will allow the constructor invocation to not set the required members while leaving invalid values. Furthermore, is there enough of an advantage in using a constructor to set non-required rather than just allowing them to be set via an object initializer. On the flip side, obviously don’t mark a value as required when the default value of the data type is valid.

As you would expect, you cannot have a required public type with a private setter. Rather, the setter on a required member must match the visibility of the type that contains the member. Since Book is public , its Isbn property setter must also be public.

One last important point to note. Adding a required member after your class is already published to production will cause existing code that instantiates the type to no longer compile because the added required members will need to be specified in the object initializer. This makes the new version incompatible with existing code; therefore, you should avoid it.

________________________________________

  • p.key == item.key) && !currentPage.some(p => p.level > item.level), }" > p.key == item.key) && !currentPage.some(p => p.level > item.level), }" :href="item.href"> Introduction
  • p.key == item.key) && !currentPage.some(p => p.level > item.level), }" > p.key == item.key), }" :href="item.href"> {{item.title}}

Dev solutions

Solutions for development problems, how to avoid getting "possible "null"assignment to a non-nullable entity".

Sorry for this awkward example, but I want to keep it as to the point as possible

Lets say, I have parsed a json-file, which gives me the hierarchy below

myobj cannot be null SubObject can be null sometimes

I have an extension method

So I expect the plusCustomers-line to be safe(empty list instead of null). But I get a warning

possible "null"assignment to a non-nullable entity

If I replace the first line with

I get rid of the warning, but that is not correct. How can I convince Resharper that this is ok?…or I’m I mistaken?

>Solution :

You can add brackets:

The effect of the null chaining ( ?. ) is to evaluate the whole chain of member accesses to null, if the LHS operand is null, rather than evaluating just that single member access to null. For example, consider a long chain of member accesses a.b.c.d.e.f . If only a is nullable, you would only need to write ? after a for this to be safe. It doesn’t just evaluate a?.b to null if a is null, because in that case you’d have to write ? after every member access for this to be safe, and that’s a bit annoying.

So without the brackets, the whole member access is made nullable due to ?. , regardless of what you call at the end.

By adding brackets, you break up the chain of member accesses, so that myObj.SubObj?.CustomerList is of a nullable type, and calling EmptyIfNull on that works as expected – returning whatever type EmptyIfNull should return.

Share this:

Leave a reply cancel reply, discover more from dev solutions.

Subscribe now to keep reading and get access to the full archive.

Type your email…

Continue reading

Navigation Menu

Search code, repositories, users, issues, pull requests..., provide feedback.

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly.

To see all available qualifiers, see our documentation .

  • Notifications

Should non-nullable types allow temporary assignment of possible null value? #4440

@SoftCircuits

{{editor}}'s edit

Softcircuits feb 14, 2021.

Beta Was this translation helpful? Give feedback.

Replies: 2 comments · 4 replies

Halofour feb 14, 2021.

@SoftCircuits

SoftCircuits Feb 14, 2021 Author

@HaloFour

333fred Feb 14, 2021 Maintainer

Rikkigibson feb 16, 2021 maintainer.

@SoftCircuits

  • Numbered list
  • Unordered list
  • Attach files

Select a reply

ReSharper 2024.1 Help

Code inspection: possible 'system.nullreferenceexception'.

ReSharper analyzes nullability of symbols and issues a warning if it detects access to members on objects that can be null references.

Note that nullability analysis is configurable , meaning that you can define in which situations ReSharper will assume values to be null references.

You can find detailed explanations of how ReSharper detects possible 'null' dereferences in the Value and nullability analysis and the Detect possible NullReferenceExceptions topics.

Techniques and tools to update your C# project - Migrating to nullable reference types - Part 4

Maarten Balliauw

Loves web and HTTP, C#, Kotlin, Azure and application performance. Developer Advocate at JetBrains . Frequent speaker at and organizer of various community events. Likes brewing his own beer.

  • Antwerp, Belgium

Techniques and tools to update your C# project - Migrating to nullable reference types - Part 4

Previously, we saw how you can help the compiler’s flow analysis understand your code , by annotating your code for nullability.

In this final post of our series, we’ll have a look at the techniques and tools that are available to migrate to using nullable reference types in an existing code base.

In this series:

  • Nullable reference types in C#
  • Internals of C# nullable reference types
  • Annotating your C# code
  • Techniques and tools to update your project (this post)

Pick your approach: there is no silver bullet

As we have seen in a previous post , it can be an overwhelming experience to go all-in and enable the nullable annotation context for all projects in your solution.

Generally speaking, it’s a good idea to fully enable the nullable annotation context for new projects. This gets you the benefits of better static flow analysis from the start.

For existing projects, the choice is yours:

  • For smaller projects, you can set <Nullable>enable</Nullable> at the project level and plow through.
  • For larger projects, you may want to leave the project level set to disable , and add #nullable enable file by file.
  • Alternatively, you can set warnings as the project level default, so you’ll see warnings where the compiler’s flow analysis infers potential null references. You can then add #nullable enable file by file, and gradually add the right annotations and nullable attributes.

Regardless of the setting you choose at the project level, you’ll be in the mode of working through all warnings incrementally.

There is no silver bullet. There are, however, some techniques and tools that will help you reach the end goal of having a fully annotated codebase.

Start at the center and work outwards

Where to begin? What worked well for me on various code bases, was to start at the center.

Try and find the classes in your project that have zero dependencies on other reference types, apart from some strings. Data Transfer Objects (DTOs) / Plain-Old CLR Objects (POCOs) almost always fall under this category.

DTOs/POCOs are often used in many places throughout your project. Updating nullability for these classes means that nullability flows through the rest of your projects, and makes usages more reliable project-wide. So even if annotating one property seems like a small thing to do, it will flow through and be meaningful in the bigger picture.

Here’s an example:

This LocationInfo class only has two properties. Converting this class to using C# nullable reference types may be easy!

Add annotations or redesign your code

Let’s enable nullable reference types for this LocationInfo class!

  • Add #nullable enable to the class file
  • If there’s a value specified at every usage, keep the class as-is.
  • If a null reference is passed in, you may need to annotate the property with ?
  • In the IDE, use Find Usages on the constructor, and determine if the constructor parameters are potentially set to null anywhere.

Going through usages, I found this particular case in my code base:

I really want to recommend using ReSharper (R#) or JetBrains Rider once more. As mentioned before, both tools ship years of experience with nullable flow analysis, and it shows.

Both R# and Rider caught that result.Country.Name and result.City.Name may be null , even with the nullable warning context set to disabled at the project level:

Possible 'null' assignment to non-nullable entity

This is one of those cases where you’ll have to decide on the approach to take…

  • Should you annotate the LocationInfo constructor parameters?
  • Should you keep the LocationInfo constructor parameters as non-nullable and update the call site?

In this case there is only one call site that potentially passes a null reference, so let’s keep the LocationInfo constructor parameters non-nullable and update the call site instead:

The call site is updated with more thorough null checks, and a redesigned API:

  • When no null values are present, we still return LocationInfo with non-nullable properties.
  • When any values are null , we return LocationInfo.Unknown - a static property with both properties set to "Unknown" . No need for null checks anywhere LocationInfo is used, there’s always going to be a value.

Much like with async / await , nullable annotations will flow through your entire project. If we annotated the properties of LocationInfo as being nullable, we’d have to do null checks in our entire project. Instead, we chose to redesign our code and set a boundary of how far potential null references can flow. In this case, not far at all.

Once again, keep in mind there’s no silver bullet. In some cases, adding a nullable annotation will be the way to go, in other cases a small (or big) redesign may be better.

Don’t be afraid of null

Before we continue, there’s something important to keep in mind. The goal of migrating to C# nullable reference types, is to gain more confidence in the flow analysis provided by the compiler and the IDE. We’re not here to completely get rid of all null usages in our code!

As part of migrating to nullable reference types, you will be annotating some reference types with ? , sometimes you’ll be suppressing warnings with ! , and sometimes, you’ll end up redesigning bits of your code.

Returning or passing around null is totally fine. Using C# nullable reference types and annotations makes doing so more reliable, with fewer chances of NullReferenceException being thrown unexpectedly. We’re building a safety net.

Nullable warning suppressions should be temporary

As part of migration, you may sprinkle some null-forgiving operators through your project’s code. When you’re not sure a reference type should be nullable or not, you can suffix the usage with the dammit-operator, ! , and suppress any nullability warnings for that code path.

What’s nice about nullable warning suppressions, is that they disables flow analysis for a certain code path. You can use it to see the effect of what would happen to a code path if a reference that currently can be null would be redefined as non-nullable.

In some cases, you will indeed need to suppress null , and its usage is valid. In most cases, however, consider nullable warning suppressions a code smell. Using ! should be a temporary thing, use it with care. Since it disables flow analysis, it could hide nullability issues in your project - the exact issue you set out to improve upon!

Tool tip: At any time during a migration, you can use ReSharper or JetBrains Rider to find all nullable warning suppressions. Use Alt+Enter on any suppression, and search for other suppressions in the current file, project, or solution.

Where is this value coming from? Where is it being used?

In many cases, Find Usages will be sufficient to get an idea of the direct usages of a class, constructor, method, or property. In other cases, you may need more information.

ReSharper (R#) and JetBrains Rider come with value tracking and call tracking to help you out here. Visual Studio 2022 also has a Track Value Source command, but your mileage with it will vary.

With value tracking, you can follow the entire flow of a specific value and determine where it is originating from and where it is being used.

Not sure if this TrackingAccount property should be annotated? The Inspect | Value Origin action will track all places where a value for this property can be assigned, and provides a tool window to jump to every location.

ReSharper Value Origin Tracking

Note that it’s also possible to do the inverse, and analyze where the value from this TrackingAccount property is used.

JetBrains Annotations to C# nullable annotations

In a previous post , we discussed JetBrains Annotations already. If you’re working on a project where these annotations were already in use before C# introduced nullable reference types, you are in luck when migrating to C#’s version!

When you enable the nullable context, ReSharper and JetBrains Rider will help you with the migration. You’ll get hints on whether certain annotations are still needed.

The ReadColumnFromCsv returns a non-nullable string , which means the [NotNull] annotation can be safely removed. The Remove redundant attribute quick fix is one Alt+Enter away!

Similarly, the [CanBeNull] string columnName parameter declaration can be updated. The original [CanBeNull] annotation can be removed, and converted to string? columnName .

Use type annotation syntax

If you’re using the 2022.1 version of ReSharper or JetBrains Rider, there is a new Migrate to #nullable enable quick fix that does a few things at once:

  • It inserts all [NotNull] and [CanBeNull] attributes inherited from base members such as implemented interfaces. JetBrains annotations can be inherited (unlike C#’s annotations), so they are pulled in.
  • It infers annotations, by looking at your code’s branches. Are you returning null ? A nullable return type will be inferred.
  • It converts all JetBrains Annotations in the current file to C# annotations.

Migrate to #nullable enable

Tip: You can run most of these quick fixes on your entire file, project or solution in one go.

Determine nullability based on null checks

When you’re annotating your code, there are often clear hints in your code about what its nullability should be.

Here’s a quiz: in the following ReadColumnFromExcel method, what should the nullability of the columnName parameter be?

If you answered string? columnName , you are right!

The first line of code in this method is checking if columnName != null , which means it should be annotated as nullable. There will be lots of these cases in the project you are migrating, and they usually provide a great hint in terms of annotating a parameter or property.

ReSharper and JetBrains Rider will detect these cases for you, and offer to fix the annotation(s) for you.

Change type of parameter to nullable

What about third-party libraries and external code?

When you are consuming third-party libraries, you’re in for a treat! Looking at the top downloaded packages on NuGet.org , not all of them are annotated. I’m sure if you look at the long tail of packages, there will be many more libraries that are not annotated at all!

Libraries with C# annotations

If you’re lucky, the library you are consuming has been fully annotated. There’s not much to say in this case: the C# compiler and all IDEs will pick up these annotations, and give you design- and compile-time hints. Great!

Libraries with JetBrains Annotations

If you’re consuming a library that ships its JetBrains Annotations, and you are using ReSharper or JetBrains Rider, you’re in luck as well.

ReSharper and JetBrains Rider will automatically recognize annotations found in the JetBrains.Annotations namespace. Sometimes, libraries ship a custom namespace. The IDE will recognize these attributes, but you’ll still need to enable them in the settings.

Here’s an example with Hangfire . This project ships their annotations in the Hangfire.Annotations namespace:

Enable Hangfire annotations

After enabling it, the IDE considers the annotations in flow analysis:

JetBrains Annotations used in flow analysis

While many libraries use JetBrains Annotations, not all of them ship them in their NuGet package.

Tip: If you have a library that is annotated with JetBrains annotations, make sure to ship them along with your code and make the life of many developers more enjoyable.

Libraries without annotations

If you are consuming libraries that are not annotated with either C#’s or JetBrains’ nullable annotations, you’ll have to do lots of null checks. Unless you dive into their source code, there is no way the compiler’s flow analysis can give you reliable hints.

If you’re using ReSharper or JetBrains Rider, you can enable pessimistic analysis to help uncover the places where you’ll need extra null checks.

Pessimistic analysis

By default, ReSharper and JetBrains Rider analyze your code in optimistic mode. In this mode, you will only see warnings about potentially dereferencing null if you explicitly checked it for null in the code path, or if it’s annotated as nullable.

The opposite mode is pessimistic . Unless a value is annotated as non-nullable, the IDE will expect you do a null check. The web help has more info about both modes .

Here’s an example. This ReadColumnFromCsv returns a non-null string . In pessimistic mode, you’ll see a warning when returning csv[columnName] . The CsvReader ’s indexer has no nullable annotations, and therefore pessimistic analysis treats it as a potential null reference.

To get rid of this warning, you’ll have to return the defaultValue when csv[columnName] is null:

Pessimistic analysis is not a mode I would recommend as the default in your projects. It’s more pessimistic than the compiler is!

It may be of help when migrating to C# nullable reference types, as it will definitely uncover some cases where you need additional null checks. Especially when working with third-party libraries that may not (yet) be annotated!

Deserializing JSON

If you have played with nullable reference types already, you may have found that there is no good way to get rid of all nullability warnings.

Typically, you will have several classes that will be used when deserializing JSON data, something like this:

With C# nullable reference types enabled, a warning will be shown for the Name property: Non-nullable property is uninitialized. Consider declaring it as nullable.

Let’s look at how we can fix these warnings…

Make the property nullable - Bad!

Following the compiler’s advice, you can update the property and make it nullable:

Done! No more warnings! However, you now have to check for Name != null anywhere you consume this property…

Add a default value and suppress the warning - Bad!

Another option would be to suppress the warning, and change the User class to the following:

Done! No more warnings! However, you are now lying to the compiler. When consuming the Name property, you may get a null reference after all.

Add a primary constructor (Newtonsoft.Json) - Good!

With Newtonsoft.Json , you can add a primary constructor that covers all properties of your class. The JSON deserializer will pick this up, and calls the constructor instead of setting the properties directly:

With this approach, you’ll get rid of nullability warnings without shooting yourself in the foot. If you don’t expect a null value from the JSON, stay close to that expectation and declare the property as non-nullable. In the constructor, you can set a default value, or throw an ArgumentNullException . Don’t blindly accept and propagate null .

Annotations and default values - Good!

Another approach to our problem would be setting a proper default value. In case no value is deserialized, and assuming the JSON deserializer doesn’t explicitly pass in null in such case, the property will be non-nullable and contain an expected default value:

This can also be accomplished using record classes, which is quite elegant for objects that are solely used for JSON deserialization:

An alternative would be to use a backing field, and make use of the [AllowNull] attribute that lets callers set null , while being certain that they will never get null when reading from this property.

Personally, I would not recommend this specific approach. It gets rid of all warnings, but it’s cumbersome to maintain with that backing field. And more importantly, since the [AllowNull] attribute works for the setter only, it can be confusing for consumers of your class.

To summarize, there are many solutions to making your JSON deserialization more reliable with C# nullable reference types. Whether you choose one of the approaches I have listed, or come up with another approach, don’t lie to the compiler, and don’t make life hard on yourself and your team by flowing potential null references around unnecessarily.

Remember that nullable warning suppressions are a code smell, and should be used with care - especially when you suppress warnings on values that are clearly null .

Be careful with Entity Framework

For most frameworks and libraries, nullable reference types and annotations are just hints to the IDE and compiler. That is, until you encounter a framework that uses the annotations for other things, such as Entity Framework.

From the documentation :

A property is considered optional if it is valid for it to contain null . If null is not a valid value to be assigned to a property then it is considered to be a required property. When mapping to a relational database schema, required properties are created as non-nullable columns, and optional properties are created as nullable columns.

In other words: if you update the nullability of an entity in C# code, a migration will be created that changes nullability in the database as well !

But what is considered “updating the nullability”? Adding or removing the nullable annotation ( ? ) is one such change, and merely adding #nullable enable (or enabling nullability project-wide) is another.

In other words: if you enable nullability in a project or file, your database may change .

The Entity Framework documentation covers the various approaches to declaring entity properties and playing nice with C# nullable reference types.

In this final post of our series, we have covered various techniques and tools that are available to migrate your existing projects to use C# nullable reference types.

The benefit (and goal) of annotating your code, is that you get design-time and compile-time hints, from the IDE and the compiler. When adding annotations, steer clear of lying to the compiler. Suppressions are an anti-pattern in all but some cases. When needed, update the design of your API instead of passing around null values without there being a need , other than making a warning go away.

Thank you for reading!

P.S.: I realize this post was also a bit of a love letter for ReSharper (R#) and JetBrains Rider . Both tools are of great help when migrating and annotating your code. If you have migrated (or are in the process of migrating), what tools are you using? What help do they offer? I would love to hear about those in the comments!

Leave a Comment

avatar

9 responses

Avatar for Khalid Abuhakmeh

Khalid Abuhakmeh • May 3rd, 2022 Great post as always Maarten! Thanks for sharing your knowledge with the community.

Avatar for Maarten Balliauw

Maarten Balliauw • May 3rd, 2022 Thank you, Khalid!

Avatar for Umut

Umut • May 4th, 2022 Great post hhanks for sharing your knowledge with the community.

Avatar for Ken Bonny

Ken Bonny • May 5th, 2022 I use a little pattern to make my code more descriptive. I use this mostly when dealing with multiple checks (isFound && valueAboveThreshold && …). It goes a bit like this: var order = GetOrder(id); var orderNotFound = order is null; if (orderNotFound) return; ... Rider/R# don’t see the guard against the null value. How do I solve this.
Maarten Balliauw • May 6th, 2022 Good question, Ken! If you look at compiler output, you’ll probably find a [CS8602] Dereference of a possibly null reference at the location you are dereferencing the order . This is one of those cases where R#/Rider have to agree with the compiler. If R#/Rider would say this is okay, but you get the compiler to say otherwise, what’s the best answer? I would argue the C# compiler, as that is ultimately the tool that converts your code into something executable.

Avatar for Vedran Mandić

Vedran Mandić • August 5th, 2022 FAN-FANTASTIC, thank you so much Maarten!

Avatar for Grigory

Grigory • August 10th, 2022 Thank you for the great articles. However, I’m a bit confused with the point: Add a default value and suppress the warning - Bad!

At the end of the article you mentioned Entity Framework. When you set up your DbContext you have a list of DbSets. E.g. in my case it looks something like this:

As you can see I lie to the compiler, and I don’t see a better way to do it here. DbSets always will be not null, because that is how EF works. Or maybe I miss something and you know the better approach?

Maarten Balliauw • August 12th, 2022 That’s definitely lying to the compiler, but alas, no other way around it in this case. I would say in this case it is fine. You could disable/enable nullability for those properties as well (using #nullable disable / enable .

Avatar for Doug Waldron

Doug Waldron • September 19th, 2022 @Grigory The Entity Framework docs address your question. If you don’t want to use the null-forgiving operator, you can alternately use this syntax: public DbSet<Customer> Customers => Set<Customer>(); public DbSet<Order> Orders => Set<Order>(); Hope that helps!

You May Also Enjoy

Talk - bringing c# nullability into existing code.

Related resources Read more »

Test-Driving Windows 11 Dev Drive for .NET

At Build 2023 back in June, Microsoft announced a new form of storage volume for Windows 11: Dev Drive. In October 2023, support for Dev Drive was shipped as a Windows Update and now available to anyone using the latest version of Windows 11. [Environment]::SetEnvironmentVariable(“npm_config_cache”, “$DevDrive\Pack... Read more »

Provide opt-in to experimental APIs using C#12 ExperimentalAttribute

When writing libraries and frameworks that others are using, it’s sometimes hard to convey that a given API is still considered “experimental”. For example, you may want to iterate on how to work with part of the code base with the freedom to break things, while still allowing others to consume that code if they are... Read more »

Discriminated Unions in C#

Discriminated unions have been a long-standing request for C#. While F# users have had discriminated unions for years, C# developers will have to wait a bit longer. Read more »

solveForum

  • Search forums
  • Solveforum All topics

[Solved] How to avoid getting "possible "null"assignment to a non-nullable entity"

  • Thread starter Cowborg
  • Start date Feb 23, 2022
  • Feb 23, 2022
possible "null"assignment to a non-nullable entity Click to expand...
SolveForum.com may not be responsible for the answers or solutions given to any question asked by the users. All Answers or responses are user generated answers and we do not have proof of its validity or correctness. Please vote for the answer that helped you in order to help others find out which is the most helpful answer. Questions labeled as solved may be solved or may not be solved depending on the type of question and the date posted for some posts may be scheduled to be deleted periodically. Do not hesitate to share your response here to help other visitors like you. Thank you, solveforum. Click to expand...

Recent Threads

Why is it okay for my .bashrc or .zshrc to be writable by my normal user.

  • Zach Huxford
  • Jun 26, 2023
SolveForum.com may not be responsible for the answers or solutions given to any question asked by the users. All Answers or responses are user generated answers and we do not have proof of its validity or correctness. Please vote for the answer that helped you in order to help others find out which is the most helpful answer. Questions labeled as solved may be solved or may not be solved depending on the type of question and the date posted for some posts may be scheduled to be deleted periodically. Do not hesitate to share your thoughts here to help others. Click to expand...

SFTP user login details real-time filtering

  • Amal P Ramesh

get nat port forwarding IP address

Using docker does not give error with sudo but using ctr does on starting a container, what are some of the latest nike soccer shoes that have gained popularity among players and enthusiasts in recent years, can't change tcp/ipv4 settings on windows 10.

possible null assignment to non nullable entity

Customer service access 2007 template

  • tintincutes

Latest posts

  • Latest: Joe
  • 12 minutes ago
  • Latest: Akshay Prabhakar
  • Latest: Dimitra
  • Latest: JukEboX
  • Latest: Vivek
  • 31 minutes ago

Newest Members

nyos777

IMAGES

  1. C# : Resharper: Possible null assignment to entity marked with notnull

    possible null assignment to non nullable entity

  2. Nullable Reference Types in C#

    possible null assignment to non nullable entity

  3. Nullability in Java and Kotlin

    possible null assignment to non nullable entity

  4. c#

    possible null assignment to non nullable entity

  5. CS8600: Converting null literal or possible null value to non-nullable

    possible null assignment to non nullable entity

  6. [Solved] Non-nullable property must contain a non-null

    possible null assignment to non nullable entity

VIDEO

  1. Required vs Required

  2. Flutter Dart Null safety: Null Aware Access and Null Aware Assignment operator

  3. Entity Framework 7

  4. Video assignment Non verbal messages/Communication

  5. Understanding ??= Null Coalescing Assignment Operator

  6. 62- C# Nullable value types(Arabic)

COMMENTS

  1. How to avoid getting "possible "null"assignment to a non-nullable entity"

    Enumerable.Empty<T>(); So I expect the plusCustomers-line to be safe (empty list instead of null). But I get a warning. possible "null"assignment to a non-nullable entity. If I replace the first line with. var customers = myObj.SubObj.CustomerList.EmptyIfNull(); I get rid of the warning, but that is not correct.

  2. c#

    How to avoid getting "possible "null"assignment to a non-nullable entity" Hot Network Questions A short fiction about an American poetess who supposedly foiled, thanks to posthumous poems, the Martian invasion described by H. G. Wells

  3. Code inspection: Possible 'null' assignment to non-nullable entity

    As soon as the annotation is there, ReSharper will check if this contract is valid: [NotNull] public object CreateNotNullableObject() { return null; // Warning: Possible 'null' assignment to entity with '[NotNull]' attribute } [NotNull] can also serve as a contract for parameters, for example if you check the parameter and throw ...

  4. Resolve nullable warnings

    This set of warnings alerts you that you're assigning a variable whose type is nonnullable to an expression whose null-state is maybe-null. These warnings are: CS8597 - Thrown value may be null. CS8600 - Converting null literal or possible null value to non-nullable type. CS8601 - Possible null reference assignment.

  5. Approaches for Resolving Nullable Warnings on Existing Codebase

    Warning: Possible NULL Assignment to Non-Nullable Type Variable. After we enable the nullable reference types feature, all the reference types by default become non-nullable. ... during the migrations, it may not be possible to discuss every entity in detail to decide its nullability. So, cutting long story short, deciding on nullability is ...

  6. Exploring the non-nullable type warnings in C# 8

    Assignments CS8600 Converting null literal or possible null value to non-nullable type. CS8601 Possible null reference assignment. CS8602 Dereference of a possibly null reference. CS8605 Unboxing a possibly null value. CS8606 Possible null reference assignment to iteration variable CS8619 Nullability of reference types in value of type 'XXX ...

  7. Resolve Non-nullable Property Must Contain a Non-null Value

    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.

  8. Non-Nullable Reference Type Properties with Constructors

    The result is that non-nullable read-write fully implemented reference type properties should have validation preventing null assignment. Non-nullable automatically implemented properties need to be limited to read-only encapsulation, with any values assigned during instantiation and validated as not null prior to assignment.

  9. Code Inspections in XAML

    Possible 'null' assignment to non-nullable entity. Xaml.AssignNullToNotNullAttribute. resharper_xaml_assign_null_to_not_null_attribute_highlighting. Warning. Grammar Issues (4 inspections) ... Possible 'null' value in the path of binding without fallback value. Xaml.PossibleNullReferenceException.

  10. Why does .NET 8 warn me that my Reference type is possibly non-nullable

    Why is .Net 8 warning me about the assignment? CS8600 - Converting null literal or possible null value to non-nullable type. Foo is nullable by default is it not since it's a reference type? This seems to add a lot of noise to my warnings that are unnecessary. Beta Was this translation helpful?

  11. How to avoid getting "possible "null"assignment to a non-nullable entity"

    The effect of the null chaining (?.) is to evaluate the whole chain of member accesses to null, if the LHS operand is null, rather than evaluating just that single member access to null. For example, consider a long chain of member accesses a.b.c.d.e.f. If only a is nullable, you would only need to write ? after a for this to be safe

  12. Should non-nullable types allow temporary assignment of possible null

    It is, which is why it will not warn if you try to consume s after this block of code. However, the assignment of a nullable value to the non-nullable variable is enough to cause the warning. If you don't want that assignment to warn you can declare s as nullable or you can use the ! operator.

  13. Code inspection: Possible 'System.NullReferenceException'

    ID: PossibleNullReferenceException. EditorConfig: resharper_possible_null_reference_exception_highlighting. You can suppress this inspection to ignore specific issues, change its severity level to make the issues less or more noticeable, or disable it altogether. ReSharper analyzes nullability of symbols and issues a warning if it detects ...

  14. C# 8.0

    Non-Nullable Reference Type. Visual Studio 2017. Nullable Reference Type is one of the most popular upcoming features of C# which may be released with C# 8.0. However, C# 8.0 has not been released yet; development is going on so till the final release, its behavior may be a little bit different than the current behavior explained in this article.

  15. Possible Null assignment to non-nullable entity

    I suspect R# can't be certain that calling the same method twice will return the same value. Try storing the value returned from GetTableName in a local variable instead.. var contentType = _db. Model. FindEntityType (content. GetType());

  16. Techniques and tools to update your C# project

    The call site is updated with more thorough null checks, and a redesigned API:. When no null values are present, we still return LocationInfo with non-nullable properties.; When any values are null, we return LocationInfo.Unknown - a static property with both properties set to "Unknown".No need for null checks anywhere LocationInfo is used, there's always going to be a value.

  17. [Solved] How to avoid getting "possible "null"assignment to a non

    Enumerable.Empty<T>(); So I expect the plusCustomers-line to be safe. But I get a warning. possible "null"assignment to a non-nullable entity. If I replace the first line with. Code: var customers = myObj.SubObj.CustomerList.EmptyIfNull(); I get rid of the warning, but that is not correct.

  18. C#, Resharper, "Possible 'null' assignment to entity" warning when it

    After I use this to check for null, Resharper still warns me that the variable I'm passing as a [NotNull] argument might be null. "Possible 'null' assignment to entity marked with 'NotNull' attribute". If I replace my use (str.IsNullOrWhiteSpace ()) with the original (string.IsNullOrWhiteSpace (str)), the warning doesn't show up.

  19. Possible null reference assignment error on FirstOrDefault

    This matches the same pattern as your OnPost(): you make the call, THEN check for null, and only use the value if it's non-null. The most important thing to remember when using non-nullable reference types is that the illusion falls apart the moment you have to use an API that can return null like FirstOrDefault(). Put another way: using non ...

  20. Possible null assignment to entity marked with notnull attribute

    Separate it out: var sourceStream = request.GetResponse().GetResponseStream(); Contract.Assume(sourceStream != null); // Let Resharper know it can't be null. using (var stream = new StreamReader(sourceStream)) This has the advantage of both documenting AND checking your assumptions! answered Mar 13, 2013 at 13:12.