質問

次の C# コードがあります。

byte rule = 0;
...
rule = rule | 0x80;

これによりエラーが発生します:

タイプ「int」を「byte」に暗黙的に変換することはできません。明示的な変換が存在します (キャストが欠落していますか?)

[アップデート:質問の最初のバージョンは間違っていました...コンパイラ出力を読み間違えました]

キャストの追加 しません 問題を解決します:

rule = rule | (byte) 0x80;

次のように書く必要があります:

rule |= 0x80;

それはただ奇妙に思えます。なぜ、 |= 演算子とは異なります | オペレーター?

コンパイラに定数をバイトとして扱うように指示する他の方法はありますか?


@ジョバンニ・ガルボ :はいといいえ。このコードは外部デバイスのフラッシュ メモリのプログラミングを処理しており、論理的にメモリの 1 バイトを表します。後でキャストすることもできましたが、これはより明白に思えました。私の C の素質が表れすぎているようです。

@ジョナサン・ホランド :「as」構文はよりきれいに見えますが、残念ながら機能しないようです...それは以下を生成します:

as 演算子は、参照型または null 許容型 ('byte' は null 非許容値型) で使用する必要があります。

役に立ちましたか?

解決

int rule = 0;
rule |= 0x80;

http://msdn.microsoft.com/en-us/library/kxszd0kx.aspx |オペレーターは、すべての値タイプに対して定義されています。これで意図した結果が得られると思います。"| ="オペレーターはオペレーターであるか、それがオペレーターを割り当てます。これは、ルール=ルールの速記です| 0x80。

C# の優れた点の 1 つは、単純にサイズに基づいて値の型を悪用するなど、クレイジーなことができることです。「int」はバイトとまったく同じですが、両方を同時に使用しようとするとコンパイラが警告をスローします。1 つ (この場合は int) を使用するだけでうまく機能します。64 ビットへの対応が心配な場合は、int32 を指定できますが、x64 モードで実行している場合でも、すべての int は int32 です。

他のヒント

C# にはバイトを表すリテラルの接尾辞がありません。u = uint、l = long、ul = ulong、f = float、m = 10 進数ですが、バイトはありません。それをキャストする必要があります。

これは機能します:

rule = (byte)(rule | 0x80);

どうやら式 'ルール| 0x80 '0x80を「const byte 0x80」として定義している場合でも、intを返します。

探している用語は「リテラル」ですが、残念ながら C# にはバイト リテラルがありません。

ここにリストがあります すべての C# リテラル.

による ECMA 仕様、72 ページ バイトリテラルはありません。次の型の整数リテラルのみ:int、uint、long、および ulong。

醜い方法でそれを行う必要があるかもしれません: http://msdn.microsoft.com/en-us/library/5bdb6693.aspx.

それからほぼ5年が経ちますが、実際にその質問に答えた人は誰もいません。

いくつかの回答では、問題はバイトリテラルの欠如であると主張していますが、これは無関係です。計算してみると (byte1 | byte2) 結果は次のタイプです int. 。たとえ「b」がバイトのリテラル接尾辞であったとしても、 (23b | 32b) まだあるだろう int.

受け入れられた回答は、次のように主張する MSDN 記事にリンクしています。 operator| はすべての整数型に対して定義されていますが、これも当てはまりません。

operator| は定義されていません byte そのため、コンパイラは通常のオーバーロード解決ルールを使用して、上で定義されているバージョンを選択します。 int. 。したがって、結果を byte それをキャストする必要があります:

rule = (byte)(rule | 0x80);

なぜそうなるのかという疑問が残ります rule |= 0x80; 仕事?

C# 仕様には、明示的な変換を省略できる複合代入に関する特別なルールがあるためです。複合代入では x op= y ルールは次のとおりです。

選択された演算子が事前定義された演算子の場合、選択された演算子の戻り値の型が x の型に明示的に変換可能、および y が x の型に暗黙的に変換可能であるか、演算子がシフト演算子の場合、演算が評価されます。として x = (T)(x op y), ここで、T は x の型です。ただし、x は 1 回だけ評価されます。

残念ながら、今までのやり方でやるしか方法はありません。リテラルをバイトとしてマークするためのサフィックスはありません。|オペレーターは、割り当てとして暗黙的な変換を提供していません(つまり初期化)になります。

どうやら式 'ルール| 0x80 '0x80を「const byte 0x80」として定義している場合でも、intを返します。

リテラルの接尾辞を含めない限り、0x80 のような数値はデフォルトで int になるというルールがあると思います。それで、表現については、 rule | 0x80, 、0x80 は int であり、ルール (バイト) は安全に int に変換できるため、結果は int になります。

C 標準によれば、式内のバイトは、定数であっても常に int にプロモートされます。ただし、両方の値が UNSIGNED である限り、上位ビットは破棄されるため、操作は正しい値を返す必要があります。

同様に、float は double などにプロモートされます。

K&Rのコピーから抜粋。それはすべてそこにあります。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top