Qu'est-ce que la nullité inconnue en C # 8?

12

En C # 8.0, nous pouvons avoir des types de référence nullables. Les documents indiquent qu'il existe 4 types de nullité. Les 3 premiers sont assez clairs mais je n'arrive pas à comprendre le point «inconnu». Les documents disent qu'il est utilisé avec des génériques, mais lorsque j'essaie d'appeler une méthode sur une variable non contrainte de type T dans les génériques, il avertit simplement comme si le type est nullable. Je ne vois pas la différence entre inconnu et annulable. Pourquoi l'inconnu existe-t-il? Comment se manifeste-t-elle?

Stilgar
la source

Réponses:

12

Prenez la méthode générique suivante:

public static T Get<T>(T value)
{
    return value;
}

Si nous l'appelons comme Get<string>(s), le retour n'est pas nul, et si nous le faisons Get<string?>(s), il est nul.

Cependant, si vous l'appelez avec un argument générique comme Get<T>(x)et Tn'est pas résolu, par exemple, c'est un argument générique pour votre classe générique comme ci-dessous ...

class MyClass<T>
{
    void Method(T x)
    {
        var result = Get<T>(x);
        // is result nullable or non-nullable? It depends on T
    }
}

Ici, le compilateur ne sait pas si finalement il sera appelé avec un type nullable ou non nullable.

Il existe une nouvelle contrainte de type que nous pouvons utiliser pour signaler qui Tne peut pas être nulle:

public static T Get<T>(T value) where T: notnull
{
    return value;
}

Cependant, là où il Tn'est pas contraint et toujours ouvert, la nullité est inconnue.

Si ces inconnues ont été traitées comme nullables, vous pouvez écrire le code suivant:

class MyClass<T>
{
    void Method(T x)
    {
        var result = Get<T>(x);
        // reassign result to null, cause we we could if unknown was treated as nullable
        result = null;
    }
}

Dans le cas où Tn'était pas annulable, nous aurions dû recevoir un avertissement. Donc, avec des types de nullité inconnus, nous voulons des avertissements lors du déréférencement, mais aussi des avertissements pour une affectation potentielle null.

Stuart
la source
Quand je fais var result = Test.Get <T> (x); result.ToString (); le compilateur se plaint de déréférencer une valeur éventuellement nulle. Je ne vois pas en quoi inconnu est différent de simplement annulable dans ce cas.
Stilgar
1
En termes d'avertissements, ils se comportent de la même manière, mais ils sont sémantiquement différents. Vous pourriez dire que la différence est académique, et si c'était votre point, je suis d'accord.
Stuart
1
J'aimerais encore savoir pourquoi la différence a été introduite. Il semble étrange d'introduire une telle distinction dans la langue à des fins académiques.
Stilgar
Mon mauvais, il suffit de relire la spécification, de mettre à jour la réponse, la dernière partie l'explique.
Stuart
1
Ah c'est plus comme ça
Stilgar