web-dev-qa-db-ja.com

なぜ?:if-elseはそうではないのに変換エラーを引き起こしますか?

次の行を使用して、コードにいくつかの変更を加えます。

uint a = b == c ? 0 : 1;

Visual Studioはこのエラーを表示します:

型 'int'を 'uint'に暗黙的に変換できません。明示的な変換が存在します(キャストを見逃していますか?)

しかし、コードを使用する場合:

uint a; 

if (b == c) 
    a = 0; 
else 
    a = 1;

エラーや警告なしで正常に動作します。どうして?

74
Ruben Aguilar

使用できない理由uint a = b == c ? 0 : 1;

式のタイプb == c ? 0 : 1intです。 この表 に示すように、intからuintへの暗黙的な変換はないため、これは許可されていません。

使用できる理由a = 0

値が定数式である場合、数値型の特別な処理があるためです。

C#仕様のセクション6.1.9から:

  • Constant-expressionの値が宛先タイプの範囲内にある場合、int型の定数式はsbyte、byte、short、ushort、uint、またはulong型に変換できます。

  • 定数式の値が負でない限り、long型の定数式はulong型に変換できます。

最初の箇条書きに示されているようにa = 0およびa = 1は、0および1は定数式であり、有効なuint値です。基本的にこれが要約すると、コンパイラはコンパイル時にこれらの変換が有効であることを簡単に判断できるため、変換が可能になります。

ちなみに、b == c最初の例の一部が定数式(たとえば、true)に変更された場合、条件演算子式全体が定数式になり、コードがコンパイルされます。

87
JLRishe

Ifb==cは定数式であり、条件演算子全体が定数式と見なされるため、int型の定数式を他のint型に変換できるルールが適用され、コンパイルされます。

明らかに、b==cは定数式ではないため、条件演算子の結果は実行時までわからないため、intからuint(定数式の場合)への暗黙的な変換を許可する免除は適用されません。

if/elseバリアントでは、実際の割り当てのbothは定数式です。

26

literals を使用して、コードを次のように正しく動作させる必要があります。

uint a = b == c ? 0U : 1U;
10
teo van kot