24 Stimmen

Warum geben die binären Operatoren von C# immer int zurück, unabhängig vom Format ihrer Eingaben?

Wenn ich zwei byte s a y b Wie kommt das?

byte c = a & b;

einen Compilerfehler über das Casting von Byte nach Int erzeugt? Dies geschieht auch dann, wenn ich ein explizites Cast vor die a y b .

Außerdem weiß ich über diese Frage aber ich weiß nicht, inwiefern das hier zutrifft. Dies scheint eine Frage des Rückgabetyps von operator &(byte operand, byte operand2) die der Compiler wie jeden anderen Operator behandeln können sollte.

27voto

Mark Byers Punkte 761508

Warum geben die bitweisen Operatoren von C# unabhängig vom Format ihrer Eingaben immer int zurück?

Ich stimme dem nicht immer zu. Dies funktioniert und das Ergebnis von a & b ist vom Typ long :

long a = 0xffffffffffff;
long b = 0xffffffffffff;
long x = a & b;

Der Rückgabetyp ist nicht int wenn eines oder beide der Argumente long , ulong o uint .


Warum geben die bitweisen Operatoren von C# int zurück, wenn ihre Eingaben Bytes sind?

Das Ergebnis von byte & byte ist ein int, weil es keine & Operator für Byte definiert. ( Quelle )

Eine & Operator existiert für int und es gibt auch einen impliziten Cast von byte à int Wenn Sie also schreiben byte1 & byte2 ist dies praktisch dasselbe wie das Schreiben ((int)byte1) & ((int)byte2) und das Ergebnis davon ist eine int .

17voto

Hans Passant Punkte 894572

Dieses Verhalten ist eine Folge des Designs von IL, der Zwischensprache, die von allen .NET-Compilern erzeugt wird. Sie unterstützt zwar die kurzen Integer-Typen (byte, sbyte, short, ushort), hat aber nur eine sehr begrenzte Anzahl von Operationen mit ihnen. Laden, Speichern, Konvertieren, Array erstellen, das ist alles. Das ist kein Zufall, denn das sind die Art von Operationen, die man auf einem 32-Bit-Prozessor effizient ausführen konnte, als IL entwickelt wurde und RISC die Zukunft war.

Die binären Vergleichs- und Verzweigungsoperationen funktionieren nur bei int32, int64, native int, native floating point, object und managed reference. Diese Operanden sind 32-Bit oder 64-Bit auf jedem aktuellen CPU-Kern, so dass der JIT-Compiler effizienten Maschinencode erzeugen kann.

Mehr dazu finden Sie in der Ecma 335, Teil I, Kapitel 12.1 und Teil III, Kapitel 1.5


Ich habe einen ausführlicheren Beitrag darüber geschrieben hier drüben .

5voto

Philippe Leybaert Punkte 161931

Binäre Operatoren sind (unter anderem) für Byte-Typen nicht definiert. In der Tat wirken alle binären (numerischen) Operatoren nur bei den folgenden einheimischen Typen:

  • int
  • uint
  • lang
  • ulong
  • Schwimmer
  • doppelt
  • dezimal

Wenn andere Typen beteiligt sind, wird einer der oben genannten verwendet.

Das steht alles in den C#-Spezifikationen Version 5.0 (Abschnitt 7.3.6.2) :

Die binäre numerische Promotion erfolgt für die Operanden der vordefinierten binären Operatoren +, -, *, /, %, &, |, ^, ==, !=, >, <, >=, und <=. Bei der binären numerischen Heraufstufung werden beide Operanden implizit in einen gemeinsamen Typ konvertiert, der im Falle der nicht-relationalen Operatoren auch der Ergebnistyp der Operation wird. Die binäre numerische Promotion besteht aus der Anwendung der folgenden Regeln, in der Reihenfolge, in der sie hier erscheinen:

  • Wenn einer der beiden Operanden vom Typ Dezimal ist, wird der andere Operand in den Typ Dezimal konvertiert, oder es tritt ein Kompilierfehler auf, wenn der andere Operand vom Typ Float oder Double ist.
  • Andernfalls, wenn einer der beiden Operanden vom Typ double ist, wird der andere Operand in den Typ double konvertiert.
  • Andernfalls, wenn einer der beiden Operanden vom Typ Float ist, wird der andere Operand in den Typ Float umgewandelt.
  • Andernfalls, wenn einer der beiden Operanden vom Typ ulong ist, wird der andere Operand in den Typ ulong konvertiert, oder es tritt ein Kompilierfehler auf, wenn der andere Operand vom Typ sbyte, short, int oder long ist.
  • Andernfalls, wenn einer der beiden Operanden vom Typ long ist, wird der andere Operand in den Typ long konvertiert.
  • Ist einer der beiden Operanden vom Typ uint und der andere Operand vom Typ sbyte, short oder int, werden beide Operanden in den Typ long konvertiert.
  • Andernfalls, wenn einer der beiden Operanden vom Typ uint ist, wird der andere Operand in den Typ uint umgewandelt.
  • Andernfalls werden beide Operanden in den Typ int konvertiert.

2voto

Mau Punkte 13706

Das liegt daran, dass & für Ganzzahlen und nicht für Bytes definiert ist und der Compiler Ihre beiden Argumente implizit in int umwandelt.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X