Was ist unbekannte Nullbarkeit in C # 8?


12

In C # 8.0 können nullbare Referenztypen vorhanden sein. In den Dokumenten wird angegeben, dass es 4 Arten der Nullbarkeit gibt. Die ersten 3 sind ziemlich klar, aber ich verstehe den Punkt "unbekannt" nicht. Die Dokumente sagen, dass es mit Generika verwendet wird, aber wenn ich versuche, eine Methode für eine nicht eingeschränkte Variable vom Typ T in Generika aufzurufen, warnt es nur, als ob der Typ nullwertfähig ist. Ich sehe keinen Unterschied zwischen unbekannt und nullbar. Warum gibt es Unbekanntes? Wie manifestiert es sich?

Antworten:


12

Nehmen Sie die folgende generische Methode:

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

Wenn wir es so nennen Get<string>(s), ist die Rückgabe nicht nullbar, und wenn wir es tun Get<string?>(s), ist sie nullbar.

Allerdings , wenn Sie es mit einem generischen Argumente wie fordern Get<T>(x)und Tnicht gelöst wird , ist es beispielsweise ein generisches Argument zu Ihrer allgemeinen Klasse wie unten ...

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

Hier weiß der Compiler nicht, ob er irgendwann mit einem nullbaren oder nicht nullbaren Typ aufgerufen wird.

Es gibt eine neue Typbeschränkung, mit der wir signalisieren können, dass Tsie nicht null sein darf:

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

Wo Tjedoch nicht eingeschränkt und noch offen ist, ist die Nullbarkeit unbekannt.

Wenn diese Unbekannten als nullwertfähig behandelt würden, könnten Sie den folgenden Code schreiben:

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

In dem Fall, in dem Tnicht nullbar war, hätten wir eine Warnung erhalten sollen. Bei unbekannten Nullbarkeitstypen möchten wir also Warnungen beim Dereferenzieren, aber auch Warnungen für die potenzielle Zuweisung null.


Wenn ich var resultiere = Test.Get <T> (x); result.ToString (); Der Compiler beschwert sich über die Dereferenzierung eines möglicherweise Nullwerts. Ich sehe nicht, wie unbekannt sich in diesem Fall von einfach nullbar unterscheidet.
Stilgar

1
In Bezug auf Warnungen verhalten sie sich gleich, unterscheiden sich jedoch semantisch. Man könnte sagen, der Unterschied ist akademisch, und wenn das Ihr Punkt war, dann stimme ich zu.
Stuart

1
Ich würde immer noch gerne wissen, warum der Unterschied eingeführt wurde. Es erscheint seltsam, eine solche Unterscheidung für akademische Zwecke in die Sprache einzuführen.
Stilgar

Mein schlechtes, lies einfach die Spezifikation noch einmal durch, aktualisiere die Antwort, der letzte Teil erklärt es.
Stuart

1
Ah, das ist eher so
Stilgar
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.