'int'と<null>の間の暗黙的な変換がないため、条件式のタイプを決定できません


回答:


338

スペック(§7.14)は、条件式のためと言うb ? x : yのいずれかで、三台の可能性があるxyの両方のタイプを持っている、特定の良好な条件が満たされている、のいずれか一方のみxyタイプ有する特定の良好な条件が満たされて、コンパイル時エラーを発生します。ここで、「特定の良好な状態」とは、特定の変換が可能であることを意味します。これについては、以下で詳しく説明します。

さて、仕様の関連部分に移りましょう:

唯一の場合の1 xy種類があり、両方xyその型に暗黙的に変換され、その条件式のタイプです。

ここでの問題は、

int? number = true ? 5 : null;

条件付き結果の1つだけにタイプがあります。ここxintリテラル、そしてyあるnullんどのないタイプを持っているnull暗黙的に変換可能ではありませんint1。そのため、「特定の良好な条件」が満たされず、コンパイル時エラーが発生します。

これ回避するに 2つの方法があります。

int? number = true ? (int?)5 : null;

ここでは、xとのいずれか1つのみが存在する場合を示しyます。ことを注意null まだ型がありませんまだ、コンパイラはのでこれですべての問題を持っていない(int?)5nullの両方に暗黙的に変換されているint?(§6.1.4および§6.1.5)。

他の方法は明らかに:

int? number = true ? 5 : (int?)null;

しかし今度は、これが大丈夫な理由を理解するために、仕様の別の節を読む必要があります。

場合はx型を持つXy種類がありY、その後

  • 暗黙の変換(§6.1)がより存在する場合XY、ではないからYX、次にY条件式のタイプがあります。

  • 暗黙の変換(§6.1)がより存在する場合YX、ではないからXY、次にX条件式のタイプがあります。

  • そうしないと、式のタイプを判別できず、コンパイル時エラーが発生します。

これxはのタイプでintyのタイプint?です。以下からの暗黙の変換がないint?のはint、しかしからの暗黙的な変換があるintint?式の型があるようにint?

1:条件式のタイプを決定する際に左側のタイプが無視されることに注意してください。これは、ここでよくある混乱の原因です。


4
これがなぜ起こるのかを説明するための仕様の良い引用-+1!
JerKimball 2013

7
別のオプションはのnew int?()代わりです(int?)null
Guvante 2013

1
これは、null許容のデータベースフィールドタイプ(たとえば、null許容のDateTime)がありDateTime、実際に必要なときにデータをにキャストしようとした場合にも当てはまります(DateTime?)
Mike Upjohn

73

null 識別可能なタイプはありません-それを幸せにするために少しプロディングが必要です:

int? number = true ? 5 : (int?)null;

2
または、次のことができますint? number = true ? 5 : null as int?;
ブラッドM

ポイントを明確にする良い答え。ニース関連の読書:ericlippert.com/2013/05/30/what-the-meaning-of-is-is
Benjamin

問題は、識別可能なタイプがないことでnullはありません。問題は、からnullへの暗黙の変換がないことintです。詳細はこちら
ジェイソン2013

おもしろいのはそれint? number = true ? 5 : (int?)null;int? number = true ? (int?)5 : null;両方がコンパイルされることです!! スクラッチ、スクラッチ
davidhq 2013

2
これが私の答えでなぜ起こるかを正確にカバーします
ジェイソン2013

4

他の人が述べたように、5はでありintnull暗黙的にに変換することはできませんint

この問題を回避する他の方法は次のとおりです。

int? num = true ? 5 : default(int?);
int? num = true ? 5 : new int?();

int? num = true ? 5 : null as int?;
int? num = true ? 5 : (int?)null;

int? num = true ? (int?)5 : null;
int? num = true ? 5 as int? : null;

int? num = true ? new int?(5) : null;

また、どこにいてint?も使用できますNullable<int>


1

ではC# 9、この今許可されているブログ

ターゲットが入力されましたか?と?

時々条件付き?and?:式には、ブランチ間で明らかな共有型がありません。このようなケースは今日失敗しますが、C#9.0は、両方のブランチが変換するターゲットタイプがある場合、それらを許可します。

Person person = student ?? customer; // Shared base type
int? result = b ? 0 : null; // nullable value type

またはあなたの例:

// Allowed in C# 9.
int? number = true ? 5 : null;
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.