O que é anulabilidade desconhecida no C # 8?

12

No C # 8.0, podemos ter tipos de referência anuláveis. Os documentos afirmam que existem 4 tipos de nulidade. Os três primeiros são bastante claros, mas não entendo o ponto "desconhecido". Os documentos dizem que é usado com genéricos, mas quando tento chamar um método em uma variável irrestrita do tipo T em genéricos, ele apenas avisa como se o tipo fosse anulável. Não vejo a diferença entre desconhecido e anulável. Por que o desconhecido existe? Como isso se manifesta?

Stilgar
fonte

Respostas:

12

Siga o seguinte método genérico:

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

Se chamarmos assim Get<string>(s), o retorno não será anulável e, se o fizermos Get<string?>(s), será anulável.

No entanto, se você estiver chamando-o com um argumento genérico como Get<T>(x)e Tnão for resolvido, por exemplo, é um argumento genérico para sua classe genérica como abaixo ...

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

Aqui, o compilador não sabe se, eventualmente, será chamado com um tipo nulo ou não nulo.

Há uma nova restrição de tipo que podemos usar para sinalizar que Tnão pode ser nulo:

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

No entanto, onde Té irrestrito e ainda está aberto, a nulidade é desconhecida.

Se essas incógnitas forem tratadas como anuláveis, você poderá escrever o seguinte 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;
    }
}

No caso em que Tnão foi anulável, deveríamos ter recebido um aviso. Portanto, com tipos de nulidade desconhecidos, queremos avisos ao fazer referência à referência, mas também avisos para atribuição potencial null.

Stuart
fonte
Quando faço var result = Test.Get <T> (x); result.ToString (); o compilador reclama de desreferenciar um valor possivelmente nulo. Não vejo quão desconhecido é diferente de simplesmente anulável neste caso.
Stilgar
11
Em termos de avisos, eles se comportam da mesma forma, mas são semanticamente diferentes. Você poderia dizer que a diferença é acadêmica, e se esse foi o seu ponto, eu concordo.
Stuart
11
Eu ainda gostaria de saber por que a diferença foi introduzida. Parece estranho introduzir essa distinção no idioma para fins acadêmicos.
Stilgar
Meu mal, basta reler as especificações, atualizar a resposta, a última parte explica.
Stuart
11
Ah, isso é mais parecido com
Stilgar