web-dev-qa-db-fra.com

Comment faire face aux types de référence nullables avec System.Text.json?

J'ai mis à niveau mon projet sur Netcore 3.0 et je suis au milieu d'un projet d'utilisation de la nouvelle fonctionnalité des types de références nullables, mais j'ai été bloqué assez rapidement en raison du problème suivant.

Disons que je consomme un REST API qui retourne le JSON suivant:

{
  "Name": "Volvo 240",
  "Year": 1989
}

Cette API renvoie toujours le nom/année, de sorte qu'ils ne sont pas nullables.

J'utiliserais cette classe simple pour la désérialisation:

public class Car
{
    public string Name {get; set;}
    public int Year {get; set;}
}

Et je voudrais désérialiser cela à une instance Car utilisant le nouveau System.Text.Json

var car = JsonSerializer.Deserialize<Car>(json);

Tout cela fonctionne, mais lors de l'activation des types de référence nullables, je reçois un avertissement dans la classe Car _ Name est déclaré non nullable mais peut être null. Je comprends pourquoi je reçois cela puisqu'il est possible d'instancier cet objet sans initialiser la propriété Name.

Si idéalement Car devrait ressembler à ceci:

public class Car
{
    public string Name { get; }
    public int Year { get; }

    public Car(string name, int year)
    {
        Name = name;
        Year = year;
    }
}

Mais cela ne fonctionne pas parce que System.Text.Json Serializer ne prend pas en charge les constructeurs avec des paramètres.

Donc, ma question est la suivante: comment devrais-je déclarer Car de sorte que Name est non involonible et le faire fonctionner avec System.Text.Json Sans obtenir "non-nullable" avertissement? `

Je ne veux pas le rendre nullable car je devrais faire des chèques nuls sur fondamentalement tout en permettant aux types de référence nullables, et puisque le REST API dans mon exemple dit qu'ils sont toujours fournis ils ne devraient pas être nullables.

14
langen

Approche légèrement alternative. System.Text.Json semble avoir aucun problème à l'aide d'un constructeur sans paramétrage privé. Donc, vous pouvez au moins faire ce qui suit:

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;
    }
}

Avantages étant:

  • L'init de l'objet de votre propre code doit être par le biais de la CTOR publique.
  • Vous n'avez pas besoin de faire = null!; sur chaque propriété.

Rester les inconvénients avec S.T.Json et Nullable Types de référence:

  • S.T.Json nécessite toujours des configurations sur les propriétés pour définir réellement les valeurs lors de la désérialisation. J'ai essayé avec des privés et ce n'est pas aller, alors nous ne pouvons toujours pas obtenir un objet immuable ...
1
benmccallum