Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Nullable reference types and constructor warnings

I'm trying to embrace C# 8's nullable references types in my project and make it smoothly work with EF Core.

Following this guide, I made my entity classes have constructors accepting all data needed for initializing their non-nullable properties:

public class MyEntity
    {
        public MyEntity(int someNumber, string name, string shortName, bool active)
        {
            SomeNumber= someNumber;
            Name = name;
            ShortName = shortName;
            Active = active;
        }

        public int SomeNumber { get; set; }
        public string Name { get; set; }
        public string ShortName { get; set; }
        public string? SomethingOptional { get; set; }
        public bool Active { get; set; }
    }

In my business case I sometimes need to update all properties of the entity. I can use property setters, but since I want to make sure I don't omit anything by doubling the initialization syntax (and in reality my entities can have 10 or more properties), I decided to create a public Update() function for convenience and call it instead of constructor body:

        public MyEntity(int someId, string name, string shortName, bool active)
        {
            Update(someId, name, shortName, active);
        }

        public void Update(int someId, string name, string shortName, bool active)
        {
            SomeNumber = someId;
            Name = name;
            ShortName = shortName;
            Active = active;
        }

Now, when creating the entity, I call the constructor, and when changing it, I call Update(). However, now the compiler gives nullability warning (CS8618) that the non-nullable properties are not initialized by the constructor. It's apparently unable to guess that calling Update will initialize them.

I've maybe overengineered it a bit with this Update() method, but now I'm curious is there a way to make the compiler trust that my constructor will initialize the properties?

like image 252
Павле Avatar asked Apr 15 '20 06:04

Павле


People also ask

What is a nullable reference type?

Nullable reference types aren't new class types, but rather annotations on existing reference types. The compiler uses those annotations to help you find potential null reference errors in your code. There's no runtime difference between a non-nullable reference type and a nullable reference type.

Should I use nullable reference types?

Although using nullable reference types can introduce its own set of problems, I still think it's beneficial because it helps you find potential bugs and allows you to better express your intent in the code. For new projects, I would recommend you enable the feature and do your best to write code without warnings.

What is #nullable disable?

#nullable disable : Sets the nullable annotation context and nullable warning context to disable. #nullable restore : Restores the nullable annotation context and nullable warning context to the project settings.


1 Answers

It is indeed a bit verbose, but you can use the [MemberNotNull] attribute in .NET 5 to tell the compiler that a method ensures a member is not null after it returns.

using System.Diagnostics.CodeAnalysis;
    
public class MyEntity
{
    [MemberNotNull(nameof(Name), nameof(ShortName))]
    public void Update(int someId, string name, string shortName, bool active)
    {
        SomeNumber = someId;
        Name = name;
        ShortName = shortName;
        Active = active;
    }
}
like image 192
Rikki Gibson Avatar answered Oct 17 '22 16:10

Rikki Gibson