61

私はこの小さなC#の癖に少し困惑しています:

与えられた変数:

Boolean aBoolValue;
Byte aByteValue;

以下をコンパイルします。

if (aBoolValue) 
    aByteValue = 1; 
else 
    aByteValue = 0;

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

aByteValue = aBoolValue ? 1 : 0;

エラーは次のように述べています:「タイプ'int'を'byte'に暗黙的に変換することはできません。」

そしてもちろん、この怪物はコンパイルされます:

aByteValue = aBoolValue ? (byte)1 : (byte)0;

何が起きてる?

編集:

VS2008、C#3.5を使用

4

3 に答える 3

69

これはかなりよくある質問です。

C#では、ほとんどの場合、内側から外側に推論します。あなたが見るとき

x = y;

xのタイプ、yのタイプ、およびyのタイプがxと割り当て互換であるかどうかを調べます。ただし、yの型を計算するときに、xの型が何であるかを知っているという事実は使用しません。

これは、複数のxが存在する可能性があるためです。

void M(int x) { }
void M(string x) { }
...
M(y); // y is assigned to either int x or string x depending on the type of y

式が何に割り当てられているかを知らなくても、式のタイプを理解できる必要があります。型情報は、式ではなく、式から流れ出します。

条件式のタイプを計算するには、結果のタイプと代替式を計算し、2つのタイプのうちより一般的なものを選択すると、それが条件式のタイプになります。したがって、あなたの例では、条件式のタイプは「int」であり、定数ではありません(条件式が定数trueまたは定数falseでない限り)。定数ではないため、バイトに割り当てることはできません。結果が定数でない場合、コンパイラーは値からではなく、型からのみ推論します。

これらすべてのルールの例外はラムダ式であり、タイプ情報コンテキストからラムダに流れます。その論理を正しく理解することは非常に困難でした。

于 2010-02-07T04:39:15.510 に答える
12

私はVS2005を使用していますが、bool&Booleanの場合は再現できますが、trueの場合は再現できません

 bool abool = true;
 Boolean aboolean = true;
 Byte by1 = (abool ? 1 : 2);    //Cannot implicitly convert type 'int' to 'byte'
 Byte by2 = (aboolean ? 1 : 2); //Cannot implicitly convert type 'int' to 'byte'
 Byte by3 = (true ? 1 : 2);     //Warning: unreachable code ;)

最も簡単な回避策はこのキャストのようです

 Byte by1 = (Byte)(aboolean ? 1 : 2);

したがって、そうです、三項演算子は定数にそれらの型をintとして「固定」させ、小さい型に収まる定数から得られる暗黙の型変換を無効にしているようです。

于 2010-02-07T03:25:15.817 に答える
7

私はあなたに良い答えを持っていないかもしれませんが、あなたが多くの場所でこれを行うならば、あなたは宣言することができます:

private static readonly Byte valueZero = (byte)0;
private static readonly Byte valueOne = (byte)1;

そしてこれらの変数だけです。constプロジェクトのローカルである場合は、使用をやめることができます。

編集:使用readonlyすることは意味がありません-これらは変更することを意図したものではありません。

于 2010-02-07T03:16:58.253 に答える