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?
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.
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.
#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.
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;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With