How to deal with nullable reference types with System.Text.Json?
UPDATE
System.Text.Json
for .NET 5 now supports parameterized constructors, so this should not be a problem anymore.
Old answer below
After reading the msdocs I found out how I could solve this issue.
So until System.Text.Json
cannot instantiate classes with parameters in their constructor, the Car
class will have to look like this:
public class Car{ public string Name { get; set; } = default!; public int Year { get; set; }}
UpdateIf you're on net5
, use the parameterized constructor support now offer as @langen points out. Else below can still be useful.
OriginalSlightly alternative approach. System.Text.Json
appears to have no problems using a private parameterless constructor. So you can at least do the following:
public class Car{ public string Name { get; set; } public int Year { get; set; } // For System.Text.Json deserialization only #pragma warning disable CS8618 // Non-nullable field is uninitialized. private Car() { } #pragma warning restore CS8618 public Car(string name, int year) { Name = name; Year = year; }}
Benefits being:
- Init of the object from your own code must be through the public ctor.
- You don't need to do
= null!;
on each property.
Remaining downside with S.T.Json and nullable reference types:
- S.T.Json still requires setters on the properties to actually set the values during deserialization. I tried with private ones and it's a no go, so we still can't get an immutable object...
Another option, for those who want to handle missing properties with meaningful exceptions:
using System;public class Car{ private string? name; private int? year; public string Name { get => this.name ?? throw new InvalidOperationException($"{nameof(this.Name)} was not set."); set => this.name = value; } public int Year { get => this.year ?? throw new InvalidOperationException($"{nameof(this.Year)} was not set."); set => this.year = value; }}