Frage

    

Diese Frage bereits eine Antwort hier:

    
            
  •              linke Bit 255 (als Byte) Verschiebung                                      7 Antworten                          
  •     
    

Ich habe diesen Code.

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

Wenn ich zu kompilieren versuchen erhalte ich:

  

Kann nicht implizit Typ ‚int‘ konvertieren   zu 'Byte'. Eine explizite Konvertierung   existiert (möglicherweise fehlt eine Besetzung?)

Warum geschieht das? Sollte nicht | zwei Bytes geben ein Byte? Sowohl der folgenden Arbeit, sicherzustellen, dass jedes Element ist ein Byte.

Encoding.ASCII.GetString(new byte[] { (dup) });
Encoding.ASCII.GetString(new byte[] { (0x80) });
War es hilfreich?

Lösung

Es ist auf diese Weise durch Design in C #, und in der Tat geht den ganzen Weg zurück zu C / C ++ - letztere auch Operanden fördert int, die Sie gerade in der Regel nicht bemerken, weil int -> char Umwandlung es implizit, während es nicht in C #. Dies gilt nicht nur für entweder |, sondern für alle arithmetischen und bitweisen Operanden - z.B. zwei bytes Zugabe wird Ihnen auch eine int geben. Ich werde den relevanten Teil der Spezifikation zitieren hier:

  

Binäre numerische Förderung erfolgt für   die Operanden des vorgegebenen +, -,   *, /,%, &, |! ^, ==, =,>, <,> = und <= binäre Operatoren. Binär   numerische Förderung implizit konvertiert   beide Operanden in einen gemeinsamen Typ, der,   im Fall der nicht-relationalen   Betreiber wird auch das Ergebnis   Art der Operation. binäre numerische   Förderung besteht die der Anwendung   folgende Regeln, sie in der Reihenfolge   erscheinen hier:

     
      
  • Wenn einer der Operanden sind die   Typ dezimal, der andere Operand   umgewandelte Dezimalzahl eingeben, oder ein   Kompilierung-Fehler tritt auf, wenn der andere   Operand vom Typ float oder double.

  •   
  • Wenn einer der beiden Operanden von   Typ double, der andere Operand   umgebaute Doppel einzugeben.

  •   
  • Ansonsten   wenn einer der Operanden den Typ float ist,   der andere Operand den Typ umgewandelt   Schwimmer.

  •   
  • Wenn einer der beiden Operanden   ist vom Typ ULONG, wird der andere Operand   Umgerechnet auf Typ ULONG oder ein   Kompilierung-Fehler tritt auf, wenn der andere   Operand vom Typ sbyte, short, int,   oder lang.

  •   
  • Wenn einer der beiden   Operand vom Typ long, die anderen   Operand konvertiert lange eingeben.

  •   
  • Wenn einer der beiden Operanden von   Typ UINT und der andere Operand von   Typ sbyte, short oder int, beide   Operanden umgewandelt lange eingeben.

  •   
  • Wenn einer der beiden Operanden von   Typ uint, wird der andere Operand   konvertiert uint zu geben.

  •   
  • Ansonsten   beide Operanden umgewandelt eingeben   int.

  •   

Ich weiß nicht, die genaue Begründung für diese, aber ich kann über einen denken. Für arithmetische Operatoren besonders, könnte es ein wenig überraschend sein für Menschen (byte)200 + (byte)100 plötzlich gleich 44 zu bekommen, auch wenn es einen Sinn macht, wenn man bedenkt, sorgfältig die beteiligten Arten. Auf der anderen Seite, int im Allgemeinen eine Art betrachtet wird, die „gut genug“ für die Arithmetik auf den meisten typischen Zahlen ist, so durch beide Argumente Förderung int, Sie eine Art bekommen „einfach funktioniert“ Verhalten für die häufigsten Fälle.

Wie, warum wurde diese Logik auch angewendet Operatoren bitweise - Ich stelle mir diese für Konsistenz so meistens ist. Es ergibt sich eine einzige einfache Regel, die für alle nicht-boolean Binärtypen üblich ist.

Aber das alles wird meist zu erraten. Eric Lippert würde wahrscheinlich derjenige sein, über die wahren Motive hinter dieser Entscheidung für C # zumindest zu fragen (obwohl es ein bisschen langweilig sein würde, wenn die Antwort ist einfach: „Es ist, wie es in C / C getan ++ und Java, und es ist gut genug herrschen, wie es ist, so sahen wir keinen Grund, sie zu ändern ").

Andere Tipps

Die wörtliche 0x80 hat den Typ "int", so dass Sie nicht sind oring Bytes.

Dass Sie es auf das Byte passieren kann [] funktioniert nur, weil 0x80 (als wörtliche) es im Bereich von Byte ist.

Bearbeiten : Auch wenn 0x80 auf ein Byte gegossen wird, würde der Code noch nicht kompiliert, da oring Bytes noch int geben. Um es kompilieren, das Ergebnis der oder auswerfen muss sein: (byte)(0x80|dup)

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

Das Ergebnis eines bitweisen Oder (|) auf zwei Bytes ist immer ein int

.
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top