質問

この質問にはすでに答えがあります:

このコードがあります。

byte dup = 0;
Encoding.ASCII.GetString(new byte[] { (0x80 | dup) });

コンパイルしようとすると、次のようになります。

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

なぜこのようなことが起こるのでしょうか?すべきではありません| 2つのバイトがバイトを与えますか?次のどちらも機能し、各項目がバイトであることが保証されます。

Encoding.ASCII.GetString(new byte[] { (dup) });
Encoding.ASCII.GetString(new byte[] { (0x80) });
役に立ちましたか?

解決

これはC#の設計による方法であり、実際、C / C ++にまでさかのぼります-後者はオペランドをintに昇格させます。暗黙的ですが、C#ではありません。これはint -> charだけに適用されるのではなく、すべての算術およびビット単位のオペランドにも適用されます2つの|を追加すると、byteも得られます。仕様の関連部分をここで引用します:

  

次の場合、2進数の昇格が行われます   定義済みの+、<!>#8211;のオペランド   *、/、%、<!> amp;、|、^、==、!=、<!> gt;、<!> lt;、<!> gt; =、および<!> lt; =二項演算子。バイナリ   数値プロモーションは暗黙的に変換します   両方のオペランドが共通タイプになり、   非リレーショナルの場合   演算子も結果になります   操作のタイプ。 2進数   プロモーションは、   ルールに従って、順番に   ここに表示されます:

     
      
  • いずれかのオペランドが   10進型、もう一方のオペランドは   タイプdecimalに変換、または   コンパイル時エラーが発生した場合   オペランドのタイプはfloatまたはdoubleです。

  •   
  • それ以外の場合、いずれかのオペランドが   double型、もう一方のオペランドは   double型に変換されます。

  •   
  • それ以外の場合、   いずれかのオペランドがfloat型の場合、   もう一方のオペランドは型に変換されます   フロート。

  •   
  • それ以外の場合、いずれかのオペランド   ulong型で、もう一方のオペランドは   タイプulongに変換、または   コンパイル時エラーが発生した場合   オペランドのタイプはsbyte、short、int、   または長い。

  •   
  • それ以外の場合、どちらか   オペランドはlong型で、もう一方は   オペランドはlong型に変換されます。

  •   
  • それ以外の場合、いずれかのオペランドが   タイプuintおよび他のオペランドは   タイプsbyte、short、またはint、両方   オペランドはlong型に変換されます。

  •   
  • それ以外の場合、いずれかのオペランドが   タイプuint、もう一方のオペランドは   uint型に変換されます。

  •   
  • それ以外の場合、   両方のオペランドが型に変換されます   int。

  •   

これの正確な理論的根拠はわかりませんが、考えてみてください。特に算術演算子の場合、関係する型を慎重に検討すると意味があったとしても、人々が突然(byte)200 + (byte)10044と等しくなるのは少し驚くかもしれません。一方、<=>は一般に<!> quot; good enough <!> quot;の型と見なされます。ほとんどの典型的な数値の算術の場合、両方の引数を<=>に昇格させると、一種の<!> quot; just works <!> quot;が得られます。最も一般的なケースの動作。

この論理がビット演算子にも適用された理由について-これは主に一貫性のためです。結果として、 all 非ブールバイナリタイプに共通の単一の単純なルールが作成されます。

しかし、これはほとんどすべて推測です。エリック・リッパーはおそらく、少なくともC#のこの決定の背後にある本当の動機について尋ねる人でしょう(ただし、答えが単に<!> quot;そのままで十分なルールなので、変更する理由はありませんでした<!> quot;)。

他のヒント

リテラル 0x80 の型は「int」であるため、バイトの論理和は計算されません。

それを byte[] に渡すことができるのは、0x80 (リテラルとして) が byte の範囲内にあるためです。

編集:0x80 がバイトにキャストされた場合でも、バイトの論理和をとると int が返されるため、コードはコンパイルされません。コンパイルするには、 or の結果をキャストする必要があります。 (byte)(0x80|dup)

byte dup = 0;
Encoding.ASCII.GetString(new byte[] { (byte)(0x80 | dup) });

2バイトのビット単位のOr(|)の結果は常にintです。

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