Frage Warum funktioniert das?: Verursacht einen Konvertierungsfehler, während if-else nicht? [Duplikat]


Diese Frage hat hier bereits eine Antwort:

Wenn ich einige Änderungen am Code vornimmt, verwende ich die nächste Zeile:

uint a = b == c ? 0 : 1;

Visual Studio zeigt mir diesen Fehler:

Der Typ 'int' kann nicht implizit in 'uint' konvertiert werden. Eine explizite Konvertierung existiert (fehlt eine Besetzung?)

Aber wenn ich den Code verwende:

uint a; 

if (b == c) 
    a = 0; 
else 
    a = 1;

Es funktioniert korrekt ohne Fehler oder Warnung. Warum?


75
2018-03-09 08:18


Ursprung


Antworten:


Warum kann ich nicht verwenden? uint a = b == c ? 0 : 1;?

Der Typ des Ausdrucks b == c ? 0 : 1 ist int. Wie gezeigt in dieser Tisch, es gibt keine implizite Konvertierung von int zu uintDas ist also nicht erlaubt.

Warum kann ich verwenden? a = 0?

Weil es eine spezielle Behandlung von numerischen Typen gibt, wenn der Wert ein konstanter Ausdruck ist.

Aus Abschnitt 6.1.9 der C # Spezifikation:

  • Ein konstanter Ausdruck vom Typ int kann in den Typ sbyte, byte, short, ushort, uint oder ulong konvertiert werden, sofern der Wert des constant-expression im Bereich des Zieltyps liegt.

  • Ein konstanter Ausdruck des Typs long kann in den Typ ulong konvertiert werden, sofern der Wert des konstanten Ausdrucks nicht negativ ist.

Wie in der ersten Kugel angegeben a = 0 und a = 1 sind beide erlaubt, weil 0 und 1 sind konstante Ausdrücke und sind gültig uint Werte. Grundsätzlich läuft das darauf hinaus, dass der Compiler zur Kompilierzeit leicht feststellen kann, dass diese Konvertierungen gültig sind, also erlaubt es ihnen.

Übrigens, wenn die b == c Teile Ihres ersten Beispiels wurden in einen konstanten Ausdruck geändert (z. true), dann wäre der gesamte Bedingungsoperator Ausdruck ein konstanter Ausdruck und der Code würde kompilieren.


87
2018-03-09 08:27



Ob  b==c Wenn der Ausdruck ein konstanter Ausdruck wäre, würde der gesamte Bedingungsoperator als ein konstanter Ausdruck betrachtet werden, und somit die Regel, die konstante Ausdrücke des Typs erlaubt int In andere int-Typen konvertiert werden würde gelten und es würde kompilieren.

Offensichtlich, b==c ist kein konstanter Ausdruck und daher kann das Ergebnis des Bedingungsoperators erst zur Laufzeit bekannt sein. Daher gilt die Ausnahme, die eine implizite Konvertierung von Ints in Uint (für konstante Ausdrücke) zulässt, nicht.

In deinem if/else Variante, beide der tatsächlichen Zuweisungen sind konstante Ausdrücke.


26
2018-03-09 08:28



Du solltest benutzen Literale damit dein Code richtig funktioniert:

uint a = b == c ? 0U : 1U;

10
2018-03-09 08:22