Non-nullable property must contain a non-null value when exiting constructor. Consider declaring the property as nullable

C#Visual Studio

C# Problem Overview


I have a simple class like this.

public class Greeting
{
    public string From { get; set; }
    public string To { get; set; } 
    public string Message { get; set; }
}

Strangely I get the following warning.

Severity	Code	Description	Project	File	Line	Suppression State
Warning	CS8618	Non-nullable property 'From' must contain a non-null value when exiting constructor. 
Consider declaring the property as nullable.	MxWork.Elsa2Wf.Tuts.BasicActivities	 
D:\work\MxWork\Elsa2.0WfLearning\MxWork.Elsa2.0Wf.Tuts\src 
\MxWork.Elsa2Wf.Tuts.BasicActivities\Messages\Greeting.cs	5	Active

I am baffled. These new kind of messages that it throws pulls down my confidence. I got them from all the three properties. And this has suddenly appeared.

Can some one please suggest how this can be mitigated.

visual studio warning message

Update

These days I have seen using default! like so, and its working.

public class Greeting
{
    public string From { get; set; } = default!;
    public string To { get; set; } = default!;
    public string Message { get; set; } = default!;
}

Also you may put a question mark symbol(?) to indicate that the type is nullable, if you feel appropriate as follows.

public class Greeting
{
    public string? From { get; set; };
    public string? To { get; set; };
    public string? Message { get; set; };
}

C# Solutions


Solution 1 - C#

If you don't want this, you can disable this by deleting the below line from the csproj file or setting it as disable. By default value is disable.

<Nullable>enable</Nullable>

Here is the official documentation.

Solution 2 - C#

The compiler is warning you that the default assignment of your string property (which is null) doesn't match its stated type (which is non-null string).

This is emitted when nullable reference types are switched on, which changes all reference types to be non-null, unless stated otherwise with a ?.

For example, your code could be changed to

public class Greeting
{
    public string? From { get; set; }
    public string? To { get; set; } 
    public string? Message { get; set; }
}

to declare the properties as nullable strings, or you could give the properties defaults in-line or in the constructor:

public class Greeting
{
    public string From { get; set; } = string.Empty;
    public string To { get; set; } = string.Empty;
    public string Message { get; set; } = string.Empty;
}

if you wish to retain the properties' types as non-null.

Solution 3 - C#

Having nullable reference types turned on will save you a lot of heartaches when it comes to running your application. The problem with a lot of warnings is that most may not cause a problem, but it may hide that one that is causing a hard-to-find bug.

There are a few gotchas in using it like the question points out and answer very well by Slate and others.

It is a very good idea to have as near as possible to zero warning.

With nullable enabled, it produces a lot of warnings. Many times the compiler just knows something could be null. However, you being smarter than the compiler you know that by the time it reaches that code it won't be null.

For example:

    public partial class Exams: ComponentBase
    {
    [Inject] private IQuestionPoolFetchService? QPoolService { get; init; }


        private async Task FetchQuestionPool()
        {
            await QPoolService.GetAllQuestionsFromText();
        }

This will throw a CS8602 warning. Because maybe somehow the DI will send a null. Of course, we know that isn't going to happen.

You could get rid of the warning with #prama like:

    public partial class Exams: ComponentBase
    {
    [Inject] private IQuestionPoolFetchService? QPoolService { get; init; }


        private async Task FetchQuestionPool()
        {
#pragma warning disables CS8602 // Dereference of a possibly null reference.
            await QPoolService.GetAllQuestionsFromText();
#pragma warning restore CS8602 // Dereference of a possibly null reference.
        }

This is very ugly code and gets worst if you have to repeat it many times.

A better solution: Using the null-forgiving operator. "!"

public partial class Exams: ComponentBase
{
[Inject] private IQuestionPoolFetchService? QPoolService { get; init; }


    private async Task FetchQuestionPool()
    {
        await QPoolService!.GetAllQuestionsFromText();
        // null-forgiving ^
    }

This tells the compiler hey, I know this could be null, but it won't be.

Solution 4 - C#

You can annotate a property directly as non-nullable.

public string Property{ get; set; } = null!;

And it will give a warning if user tries to set the Property as null

Solution 5 - C#

You can also implement a constructor to remove the error.

public class Greeting
{
    public string From { get; set; }
    public string To { get; set; }
    public string Message { get; set; }

    public Greeting(string from, string to, string message)
    {
        From = from;
        To = to;
        Message = message;
    }
}

Solution 6 - C#

For Entity Framework Working with nullable reference types:

public class NullableReferenceTypesContext : DbContext {
    public DbSet<Customer> Customers => Set<Customer>();
    public DbSet<Order> Orders => Set<Order>();
}

Solution 7 - C#

When I searched for this question, specifically for Blazor WebAssembly [WASM], I found an alternative to Darryl Wagoner WA1GON's answer.

Using [DisallowNull] which is a precondition guard according to Microsoft's docs on Attributes for null-state static analysis interpreted by the C# compiler. It is well worth reading about more in-depth.

public partial class UploadView : FluxorComponent
{
    private static readonly Serilog.ILogger logger = Serilog.Log.ForContext<UploadView>();

    [Parameter][DisallowNull] public string? UploadHeader { get; set; }
    [Parameter][DisallowNull] public EventCallback<SaveFile>? OnUploaded { get; set; }

    [Inject][DisallowNull] private IState<UploadViewState>? State { get; set; }
    [Inject][DisallowNull] private IDispatcher? Dispatcher { get; set; }

// NOTE: I included this as an example of trying to use the null-forgiveness / old school approach 
    public UploadViewState Model {
        get {
            if (State is null) { logger.Warning("{@Component}.Model - State is null", GetType().Name); }
            if (State?.Value is null) { logger.Warning("{@Component}.Model - State.Value is null", GetType().Name); }

            return State!.Value!;
        }
    }

    protected override void OnInitialized()
    {       
        base.OnInitialized();

        Dispatcher.Dispatch(new Initialized());
        Dispatcher.Dispatch(new UploadFileSizeChanged(524288000));

        logger.Debug("{@Component} - Initialized", GetType().Name);
    }

// yada yada...
}

NOTE: If this seems like a lot of work for you to maintain you can use this Fody Weaver to have it done for you.

Solution 8 - C#

Just put:

#nullable disable

at the top of a Razor Page

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionVivekDevView Question on Stackoverflow
Solution 1 - C#vivek nunaView Answer on Stackoverflow
Solution 2 - C#SlateView Answer on Stackoverflow
Solution 3 - C#Darryl Wagoner WA1GONView Answer on Stackoverflow
Solution 4 - C#Simon LehmannView Answer on Stackoverflow
Solution 5 - C#MeloyView Answer on Stackoverflow
Solution 6 - C#Zachary ScottView Answer on Stackoverflow
Solution 7 - C#jjhayterView Answer on Stackoverflow
Solution 8 - C#AlfiView Answer on Stackoverflow