¿Qué es la nulabilidad desconocida en C # 8?

12

En C # 8.0 podemos tener tipos de referencia anulables. Los documentos indican que hay 4 tipos de nulabilidad. Los primeros 3 son bastante claros, pero no entiendo el punto de "desconocido". Los documentos dicen que se usa con genéricos, pero cuando trato de llamar a un método en una variable no restringida de tipo T en genéricos, solo advierte como si el tipo fuera anulable. No veo la diferencia entre desconocido y anulable. ¿Por qué existe lo desconocido? ¿Cómo se manifiesta?

Stilgar
fuente

Respuestas:

12

Tome el siguiente método genérico:

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

Si lo llamamos así Get<string>(s), el retorno no es anulable, y si lo hacemos Get<string?>(s), es anulable.

Sin embargo, si lo está llamando con un argumento genérico como Get<T>(x)y Tno se resuelve, por ejemplo, es un argumento genérico para su clase genérica como se muestra a continuación ...

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

Aquí el compilador no sabe si finalmente se llamará con un tipo anulable o no anulable.

Hay una nueva restricción de tipo que podemos usar para señalar que Tno puede ser nula:

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

Sin embargo, donde Tno está restringido y todavía está abierto, se desconoce la nulabilidad.

Si estas incógnitas se trataran como anulables, podría escribir el siguiente código:

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

En el caso de que Tno fuera anulable, deberíamos haber recibido una advertencia. Entonces, con tipos de nulabilidad desconocidos, queremos advertencias al desreferenciar, pero también advertencias para asignar potencialmente null.

Stuart
fuente
Cuando hago var result = Test.Get <T> (x); result.ToString (); el compilador se queja de desreferenciar un valor posiblemente nulo. No veo cuán desconocido es diferente de simplemente anulable en este caso.
Stilgar
1
En términos de advertencias, se comportan igual, pero son semánticamente diferentes. Se podría decir que la diferencia es académica, y si ese era su punto, entonces estoy de acuerdo.
Stuart
1
Todavía me gustaría saber por qué se introdujo la diferencia. Parece extraño introducir tal distinción en el lenguaje con fines académicos.
Stilgar
Lo malo, solo vuelve a leer la especificación, actualiza la respuesta, la última parte lo explica.
Stuart
1
Ah que me gusta más
Stilgar-