なぜこれはコンパイルされないのですか?
int? number = true ? 5 : null;
'int'と<null>の間に暗黙的な変換がないため、条件式のタイプを判別できません
仕様(§7.14)では、条件式b ? x : y
には3つの可能性があり、x
とy
の両方のタイプがand特定良好な条件を満たす、x
とy
のどちらか一方のタイプのみがand特定の良好な条件を満たすか、コンパイル時エラーが発生します。ここで、「特定の良好な条件」とは、特定の変換が可能であることを意味します。これについては、以下で詳しく説明します。
それでは、仕様のドイツ語の部分を見てみましょう。
x
とy
の1つだけに型があり、x
とy
の両方が暗黙的にその型に変換可能な場合、それは条件式の型です。
ここでの問題は
int? number = true ? 5 : null;
条件付き結果の1つだけに型があります。ここで、x
はint
リテラルであり、y
はnull
であり、これはnotはタイプを持ち、null
はint
に暗黙的に変換できません1。したがって、「特定の良好な条件」は満たされず、コンパイル時エラーが発生します。
areこれを回避する2つの方法:
int? number = true ? (int?)5 : null;
ここでは、x
とy
のどちらか一方だけが型を持っている場合があります。 null
stillには型がありませんが、(int?)5
とnull
は両方とも暗黙的にint?
(§6.1.4および§6.1.5)。
他の方法は明らかに:
int? number = true ? 5 : (int?)null;
しかし今では、なぜこれが大丈夫なのかを理解するために、仕様のdifferent句を読む必要があります。
x
の型がX
であり、y
の型がY
である場合
X
からY
に暗黙的な変換(§6.1)が存在し、Y
からX
に存在しない場合、Y
が条件式のタイプです。
Y
からX
に暗黙的な変換(§6.1)が存在し、X
からY
に存在しない場合、X
が条件式のタイプです。そうでない場合、式のタイプを判別できず、コンパイル時エラーが発生します。
ここで、x
はタイプint
であり、y
はタイプint?
です。 int?
からint
への暗黙的な変換はありませんが、int
からint?
への暗黙的な変換があるため、式のタイプはint?
です。
1:条件式のタイプを決定する際、左側のタイプは無視されることに注意してください。これは、ここでの混乱の一般的な原因です。
null
には識別可能なタイプはありません-それを幸せにするためにはちょっとした工夫が必要です:
int? number = true ? 5 : (int?)null;