6

基本的に、C# で以下が無効なのはなぜですか? 私はそれの良い使い方をたくさん見つけることができ、実際に独自のnull許容構造体クラスを作成することで修正できますが、C#仕様(したがってコンパイラ)がそれを防ぐ理由と方法は何ですか?

以下は、私が話していることの部分的な例です。

struct MyNullable<T> where T : struct
{
    public T Value;
    public bool HasValue;

    // Need to overide equals, as well as provide static implicit/explit cast operators
}

class Program
{
    static void Main(string[] args)
    {
        // Compiles fine and works as expected
        MyNullable<Double> NullableDoubleTest;
        NullableDoubleTest.Value = 63.0;

        // Also compiles fine and works as expected
        MyNullable<MyNullable<Double>> NullableNullableTest;
        NullableNullableTest.Value.Value = 63.0;

        // Fails to compile...despite Nullable being a struct
        // Error: The type 'double?' must be a non-nullable value type in order to use it as parameter 'T' in the generic type or method 'ConsoleApplication1.MyNullable<T>'
        MyNullable<Nullable<Double>> MyNullableSuperStruct;
    }
}
4

2 に答える 2

9

ですstruct。値型のジェネリック型パラメーターの制約を満たしていないだけです。言語仕様の 10.1.5 から:

値の型の制約は、型パラメーターに使用される型引数が null 非許容値型でなければならないことを指定します。値の型の制約を持つすべての null 非許容の構造体型、列挙型、および型パラメーターは、この制約を満たします。値型として分類されますが、null 許容型 (§4.1.10) は値型の制約を満たさないことに注意してください。

だから、where T : structあなたがそれが意味すると思うことを意味するわけではありません。

基本的に、C# で以下が無効なのはなぜですか?

null 非許容値型でwhere T : structある場合にのみ満たすことができるためです。はこの制約を満たしていません。TNullable<TNonNullableValueType>

コンパイラがそれを防ぐ理由と方法

なんで?仕様と一致すること。どのように?構文解析と意味解析を実行しT、ジェネリック型の制約を満たさないジェネリック型パラメーターを指定したことを確認しますwhere T : struct

[I]独自のnull許容構造体クラスを作成することで修正できますが、

いいえ、あなたのバージョンでは修正されません。Nullable<T>コンパイラによる特別な処理を受けないことを除いて、基本的には とまったく同じです。コンパイラの実装ではボックス化されないボックス化が発生します。

私はそれの良い使い方をたくさん見つけることができます

本当に?そのような?の基本的な考え方は、 「値が欠落している」Nullable<T>ことを格納Tまたは表すことができる保管場所を持つことです。これをネストするポイントは何ですか?つまり、のポイントはNullable<Nullable<T>>何ですか? 概念的にも意味がありません。それが禁止されている理由かもしれませんが、私は単に憶測にすぎません ( Eric Lippert は、この憶測が正しいことを確認しています)。たとえば、 とは何int??ですか? これは、値が欠落しているか、または であることint?を表す保管場所を表します。これは、値が欠落しているか、またはint?であることを表す保管場所です。使用は何ですか?

于 2012-04-17T18:12:19.910 に答える
2

T?struct 制約のダイアローイング nullables の 1 つの理由は、ジェネリック メソッドで使用できるようにするためです。null 許容値型が許可されている場合struct、コンパイラは を禁止する必要がありT?ます。

null 許容型は、他の場合でもコンパイラで特別な処理を行う必要があります。

  • null キーワードは、null 許容型に暗黙的に変換できる必要があります。これは値型では不可能です。
  • Null 許容値型は、null キーワードと比較できます。Null 非許容型の場合、この比較は常に false を返します。
  • Null 許容値の型は、??演算子で機能します。nullable でないものはそうではありません。
于 2012-04-17T18:19:09.877 に答える