OR-ing Bytes in C # gibt int [Duplikat]
-
06-07-2019 - |
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) });
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 byte
s 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
.