Ich habe experimentiert mit ILSpy, um die Ausgabe zu untersuchen, und das ist, was ich entdeckt habe.
Offensichtlich in Ihrem zweiten Fall ist dies ein Fehler - Sie können eine ulong
und eine int
nicht vergleichen, da es keinen Typ gibt, den Sie beide erzwingen können. A ulong
könnte für eine long
zu groß sein, und eine int
könnte negativ sein.
In Ihrem ersten Fall ist der Compiler jedoch clever. Es realisiert, dass const 1
> const 32
ist nie wahr, und enthält Ihre if
Anweisung in der kompilierten Ausgabe überhaupt nicht. (Es sollte eine Warnung für nicht erreichbaren Code geben.) Es ist das gleiche, wenn Sie eine const int
anstelle eines Literals definieren und verwenden, oder sogar wenn Sie das Literal explizit umwandeln (d. H. (int)32
).
Aber dann ist nicht der Compiler erfolgreich eine ulong
mit einem int
zu vergleichen, was wir gerade gesagt, unmöglich war?
Offenbar nicht. Also was ist los?
Versuchen Sie stattdessen, etwas in den folgenden Zeilen zu tun. (Unter-Eingang und Schreiben Ausgang so dass der Compiler hat nichts kompilieren entfernt.)
const int thirtytwo = 32;
static void Main(string[] args)
{
ulong x = ulong.Parse(Console.ReadLine());
bool gt = x > thirtytwo;
Console.WriteLine(gt);
}
Dies kompiliert, obwohl die ulong
ist eine Variable, und obwohl das Ergebnis wird bei der Kompilierung nicht bekannt. Werfen Sie einen Blick auf die Ausgabe in ILSpy:
private static void Main(string[] args)
{
ulong x = ulong.Parse(Console.ReadLine());
bool gt = x > 32uL; /* Oh look, a ulong. */
Console.WriteLine(gt);
}
So ist der Compiler in der Tat ist Ihre const int
als eine ulong
behandeln. Wenn Sie thirtytwo = -1
machen, kann der Code nicht kompiliert werden, obwohl wir dann wissen, dass gt
immer sein wird. Der Compiler selbst kann ulong
nicht mit int
vergleichen.
Beachten Sie auch, dass, wenn Sie x
eine long
anstelle eines ulong
machen, der Compiler 32L
erzeugt anstatt 32
als eine ganze Zahl, auch wenn dies nicht der Fall haben zu. (Sie können einen int
und long
zur Laufzeit vergleichen.)
Dies weist auf die Compiler nicht 32
als ulong
im ersten Fall behandeln, weil es zu hat, nur weil es die Art der x
bieten kann . Es spart der Laufzeit, die Konstante zu erzwingen, und das ist nur ein Bonus, wenn der Zwang eigentlich nicht möglich sein sollte.
Der Grund für diesen Fehler ist klar. Im zweiten Beispiel versuchen Sie, eine ungültige Operation mit einer Ganzzahl auszuführen. Im ersten Beispiel wird "32" als "ulong" behandelt. Du solltest "Maske" tatsächlich zu einem "ulong" machen. –
@Ramhound Entweder das (vergleiche 'ein' ulong'), oder 'compare' eine' const' Variable, also 'const int compare = 32;'. Constant Expressions werden zur Kompilierungszeit automatisch von "int" in "ulong" konvertiert, wenn sie nicht negativ sind, was unter dem Namen _Implicit constant expression conversions_ steht. –