web-dev-qa-db-ja.com

?を使用したNullable型の問題:条件演算子

誰かがこれがC#.NET 2.0で機能する理由を説明できますか?

    Nullable<DateTime> foo;
    if (true)
        foo = null;
    else
        foo = new DateTime(0);

...しかし、これはしません:

    Nullable<DateTime> foo;
    foo = true ? null : new DateTime(0);

後者のフォームでは、コンパイルエラー「「<null>」と「System.DateTime」の間に暗黙的な変換がないため、条件式のタイプを判別できません」が表示されます。

前者を使用できないわけではありませんが、2番目のスタイルは、残りのコードとより一貫しています。

152
Nick Gotch

この質問はすでに何度も聞かれています。コンパイラは、nullDateTimeに変換する方法がわからないことを伝えています。

解決策は簡単です。

DateTime? foo;
foo = true ? (DateTime?)null : new DateTime(0);

ご了承ください Nullable<DateTime>と書くことができますDateTime?これにより、入力の手間が省けます。

318
Stewart Johnson

参考までに(オフトピック、しかし気の利いた、null許容型に関連する)null結合演算子と呼ばれるnull許容型のみに便利な演算子があります。

??

このように使用します:

// Left hand is the nullable type, righthand is default if the type is null.
Nullable<DateTime> foo;
DateTime value = foo ?? new DateTime(0);
18
FlySwat

これは、三項演算子では、2つの値が同じ型に解決される必要があるためです。

8
MojoFilter

この質問は2008年に尋ねられたもので、5年後になりましたが、答えとしてマークされた答えは私を満足させません。本当の答えは、DateTimeは構造体であり、構造体としてはnullと互換性がないということです。あなたはそれを解決する2つの方法があります:

最初は、nullをDateTimeと互換性があるようにすることです(たとえば、70回の賛成票を持つ紳士が示唆するように、nullをDateTimeにキャストするか、nullをObjectまたはValueTypeにキャストします)。

2つ目は、DateTimeをnullと互換にすることです(たとえば、DateTimeをDateTimeにキャストしますか?)。

3
Mishax

受け入れられているものに似た別の解決策は、C#の default キーワードを使用することです。ジェネリックを使用して定義されていますが、実際にはあらゆるタイプに適用できます。

OPの質問に適用される使用例:

Nullable<DateTime> foo;
foo = true ? default(DateTime) : new DateTime(0);

現在受け入れられている回答の使用例:

DateTime? foo;
foo = true ? default(DateTime) : new DateTime(0);

また、defaultを使用することで、変数にnullable値を割り当てるために変数をnullとして指定する必要がなくなります。コンパイラーは、特定の変数タイプのデフォルト値を自動的に割り当て、エラーは発生しません。例:

DateTime foo;
foo = true ? default(DateTime) : new DateTime(0);
3
newfurniturey