C#8の不明なnull可能性とは何ですか?


12

C#8.0では、null許容の参照型を使用できます。ドキュメントでは、null可能性には4つのタイプがあると述べています。最初の3つは非常に明確ですが、「不明」のポイントを理解できません。ドキュメントはそれがジェネリックで使用されると言いますが、ジェネリックでT型の制約のない変数でメソッドを呼び出そうとすると、型がnull可能であるかのように警告するだけです。unknownとnullableの違いはわかりません。なぜ未知数が存在するのですか?それはどのように現れますか?

回答:


12

次のジェネリックメソッドを使用します。

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

のように呼び出すとGet<string>(s)、戻り値はnull可能ではなくGet<string?>(s)、の場合はnull可能です。

しかし、あなたのような汎用的な引数を指定して、それを呼び出している場合Get<T>(x)と、T例えば、それは以下のようなあなたのジェネリッククラスのジェネリック引数で、解決されません...

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

ここで、コンパイラーは、最終的にそれがヌル可能タイプまたは非ヌル可能タイプで呼び出されるかどうかを知りません。

Tnullにできないことを通知するために使用できる新しい型制約があります。

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

ただし、Tが制約されておらず、まだ開いている場合、NULL可能かどうかは不明です。

これらの未知数がnull可能として扱われた場合、次のコードを書くことができます:

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

Tnull可能ではなかった場合、警告が表示されます。したがって、null許容型が不明な場合、逆参照するときに警告を表示するだけでなく、を割り当てる可能性があるという警告も表示しますnull


var result = Test.Get <T>(x);を実行すると result.ToString(); コンパイラはnullの可能性がある値の逆参照について文句を言います。この場合、unknownがnull可能とどのように異なるかはわかりません。
スティルガー

1
警告に関しては同じように動作しますが、意味的には異なります。違いはアカデミックであると言えるかもしれませんが、それがあなたの主張であるなら、私は同意します。
スチュアート

1
違いが導入された理由を知りたいのですが。学術目的でこのような区別を言語に導入するのは奇妙に思えます。
スティルガー

私の悪い点は、仕様をもう一度読んで答えを更新するだけです。最後の部分で説明します。
スチュアート

1
あれはもっと似ている
スティルガー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.