web-dev-qa-db-ja.com

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

なぜこれはコンパイルされないのですか?

int? number = true ? 5 : null;

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

135
davidhq

仕様(§7.14)では、条件式b ? x : yには3つの可能性があり、xyの両方のタイプがand特定良好な条件を満たす、xyのどちらか一方のタイプのみがand特定の良好な条件を満たすか、コンパイル時エラーが発生します。ここで、「特定の良好な条件」とは、特定の変換が可能であることを意味します。これについては、以下で詳しく説明します。

それでは、仕様のドイツ語の部分を見てみましょう。

xyの1つだけに型があり、xyの両方が暗黙的にその型に変換可能な場合、それは条件式の型です。

ここでの問題は

int? number = true ? 5 : null;

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

areこれを回避する2つの方法:

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

ここでは、xyのどちらか一方だけが型を持っている場合があります。 nullstillには型がありませんが、(int?)5nullは両方とも暗黙的に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:条件式のタイプを決定する際、左側のタイプは無視されることに注意してください。これは、ここでの混乱の一般的な原因です。

279
jason

nullには識別可能なタイプはありません-それを幸せにするためにはちょっとした工夫が必要です:

int? number = true ? 5 : (int?)null;
62
Marc Gravell