Frage

Ich habe den folgenden C#-Code:

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

was den Fehler erzeugt:

Der Typ „int“ kann nicht implizit in „byte“ konvertiert werden.Es liegt eine explizite Konvertierung vor (fehlt Ihnen eine Besetzung?)

[Aktualisieren:Die erste Version der Frage war falsch ...Ich habe die Compiler-Ausgabe falsch verstanden]

Besetzung hinzufügen nicht das Problem lösen:

rule = rule | (byte) 0x80;

Ich muss es so schreiben:

rule |= 0x80;

Was einfach seltsam erscheint.Warum ist der |= Betreiber anders als der | Operator?

Gibt es eine andere Möglichkeit, den Compiler anzuweisen, die Konstante als Byte zu behandeln?


@ Giovanni Galbo :Ja und nein.Der Code befasst sich mit der Programmierung des Flash-Speichers in einem externen Gerät und stellt logisch ein einzelnes Byte Speicher dar.Ich könnte es später wirken, aber das schien offensichtlicher zu sein.Ich schätze, meine C-Erbe kommt zu sehr durch!

@ Jonathan Holland :Die 'as'-Syntax sieht übersichtlicher aus, scheint aber leider nicht zu funktionieren ...es produziert:

Der as-Operator muss mit einem Referenztyp oder einem NULL-fähigen Typ verwendet werden („Byte“ ist ein nicht NULL-fähiger Werttyp).

War es hilfreich?

Lösung

int rule = 0;
rule |= 0x80;

http://msdn.microsoft.com/en-us/library/kxszd0kx.aspx Das | Der Bediener ist für alle Werttypen definiert.Ich denke, dass dies zum gewünschten Ergebnis führen wird.Der Operator "| =" ist ein oder dann ein Operator zuordnen, was einfach für Regel = Regel | 0x80.

Eines der raffinierteren Dinge an C# ist, dass Sie damit verrückte Dinge tun können, wie zum Beispiel den Missbrauch von Werttypen einfach aufgrund ihrer Größe.Ein „int“ ist genau das Gleiche wie ein Byte, außer dass der Compiler Warnungen ausgibt, wenn Sie versuchen, sie gleichzeitig als beides zu verwenden.Es funktioniert gut, einfach bei einem zu bleiben (in diesem Fall int).Wenn Sie Bedenken hinsichtlich der 64-Bit-Bereitschaft haben, können Sie int32 angeben, aber alle Ints sind int32s, auch wenn sie im x64-Modus ausgeführt werden.

Andere Tipps

C# hat kein Literalsuffix für Byte.u = uint, l = long, ul = ulong, f = float, m = dezimal, aber kein Byte.Du musst es wirken.

Das funktioniert:

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

Anscheinend die Ausdrucksregel | 0x80 'Gibt einen int zurück, selbst wenn Sie 0x80 als' const byte 0x80 'definieren.

Der gesuchte Begriff ist „Literal“ und leider gibt es in C# kein Byte-Literal.

Hier ist eine Liste von alle C#-Literale.

Entsprechend der ECMA-Spezifikation, S. 72 Es gibt kein Byte-Literal.Nur ganzzahlige Literale für die Typen:int, uint, long und ulong.

Sieht so aus, als müssten Sie es einfach auf die hässliche Art und Weise tun: http://msdn.microsoft.com/en-us/library/5bdb6693.aspx.

Fast fünf Jahre später hat niemand die Frage wirklich beantwortet.

In einigen Antworten wird behauptet, das Problem sei das Fehlen eines Byte-Literals, aber das ist irrelevant.Wenn Sie rechnen (byte1 | byte2) Das Ergebnis ist vom Typ int.Auch wenn „b“ ein wörtliches Suffix für Byte wäre, wäre der Typ von (23b | 32b) wäre es immer noch int.

Die akzeptierte Antwort verweist auf einen MSDN-Artikel, der dies behauptet operator| ist für alle Integraltypen definiert, aber das ist auch nicht wahr.

operator| ist nicht definiert byte Daher verwendet der Compiler seine üblichen Überlastungsauflösungsregeln, um die Version auszuwählen, auf der definiert ist int.Wenn Sie also das Ergebnis a zuordnen möchten byte Sie müssen es wirken:

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

Es bleibt die Frage, warum rule |= 0x80; arbeiten?

Weil die C#-Spezifikation eine spezielle Regel für die zusammengesetzte Zuweisung enthält, die es Ihnen ermöglicht, die explizite Konvertierung wegzulassen.In der zusammengesetzten Aufgabe x op= y die Regel ist:

Wenn der ausgewählte Operator ein vordefinierter Operator ist, wenn der Rückgabetyp des ausgewählten Operators explizit in den Typ x konvertierbar ist und wenn y implizit in den Typ x konvertierbar ist oder der Operator ein Verschiebungsoperator ist, wird die Operation ausgewertet als x = (T)(x op y), wobei T der Typ von x ist, außer dass x nur einmal ausgewertet wird.

Leider besteht Ihre einzige Möglichkeit darin, es genau so zu machen, wie Sie es getan haben.Es gibt kein Suffix, um das Literal als Byte zu kennzeichnen.Das | Der Bediener sieht keine implizite Konvertierung als Aufgabe vor (dhInitialisierung) würde.

Anscheinend die Ausdrucksregel | 0x80 'Gibt einen int zurück, selbst wenn Sie 0x80 als' const byte 0x80 'definieren.

Ich denke, die Regel lautet, dass Zahlen wie 0x80 standardmäßig int sind, es sei denn, Sie fügen ein Literalsuffix ein.Also für den Ausdruck rule | 0x80, das Ergebnis ist ein int, da 0x80 ein int ist und die Regel (die ein Byte ist) sicher in int konvertiert werden kann.

Gemäß dem C-Standard werden Bytes in Ausdrücken IMMER zu int hochgestuft, auch in Konstanten.Solange jedoch beide Werte UNSIGNED sind, werden die höherwertigen Bits verworfen, sodass die Operation den richtigen Wert zurückgeben sollte.

In ähnlicher Weise fördern Floats das Double usw.

Ziehen Sie die Kopie von K&R heraus.Es ist alles drin.

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