Warum brauche ich eine Zwischenkonvertierung, um von struct nach dezimal zu gehen, aber nicht struct nach int?

8

Ich habe eine Struktur wie diese, mit einer expliziten Konvertierung in float:

%Vor%

Ich kann TwFix32 mit einer expliziten Umwandlung in int konvertieren: (int)fix32

Aber um es in Dezimal umzuwandeln, muss ich zwei Umwandlungen verwenden: (decimal)(float)fix32

Es gibt keine implizite Konvertierung von float zu int oder decimal. Warum lässt der Compiler die Zwischenformatierung weglassen, wenn ich zu int gehe, aber nicht, wenn ich auf Dezimalstelle gehe?

    
Jesse McGrew 10.05.2010, 22:11
quelle

1 Antwort

8

Ich bin oft ratlos, um eine befriedigende Antwort auf die "Warum" -Fragen zu geben.

Der Grund, warum der C # -Compiler dieses Verhalten aufweist, ist, dass er (in diesem Fall mindestens (*)) eine korrekte Implementierung der C # -Spezifikation ist.

In Abschnitt 6.4.5 der Spezifikation wird beschrieben, wie benutzerdefinierte Konvertierungen analysiert werden. Ein sorgfältiges Lesen dieses Abschnitts wird erklären, warum die explizite Umwandlung in int zulässig ist, aber in dezimal nicht.

Genauer gesagt lautet der relevante Absatz:

  

Finden Sie die Menge anwendbarer benutzerdefinierter und hochgestellter Konvertierungsoperatoren U. Dieser Satz besteht aus den benutzerdefinierten und aufgehobenen impliziten oder expliziten Konvertierungsoperatoren, die von den Klassen oder Strukturen in D deklariert werden, die von einem Typ konvertieren, der umfasst oder umfasst ist S zu einem Typ, der T umfasst oder umfasst. Wenn U leer ist, ist die Konvertierung undefiniert, und es tritt ein Fehler bei der Kompilierung auf.

In Ihrem Fall ist S TwFix und T ist entweder int oder dezimal. Die einzige benutzerdefinierte explizite Konvertierung für TwFix gibt einen Gleitkommawert zurück. int ist von float umfasst, aber dezimal ist weder von float noch von floats umfasst. Daher hat die Menge U in einem Fall ein Mitglied und ist in dem anderen leer. Daher erzeugt ein Fall einen Fehler, wie die Spezifikation sagt, und der andere nicht.

Ich habe das Gefühl, dass diese Antwort nicht befriedigend ist. Wenn nicht, können Sie die Frage so umformulieren, dass sie nicht das Wort "warum" enthält? Ich bin viel besser darin, "was" oder "wie" Fragen zu beantworten als "warum" Fragen.

(*) Der Compiler hat Fehler im Code, die berechnen, ob ein Typ einen anderen enthält, um zu bestimmen, welche integrierten Konvertierungen relevant sind, wenn die Semantik einer bestimmten benutzerdefinierten Konvertierung analysiert wird. In vielen Fällen beheben wir diese Fehler absichtlich nicht, da dies eine bahnbrechende Änderung des Codes in der realen Welt ohne großen Nutzen bedeutet. Ich möchte diesen Abschnitt der Spezifikation sehr gerne noch einmal aufgreifen und neu schreiben, um das Konzept des "umfassenden Typs" zu beseitigen. es ist ein bisschen eine Kuriosität in der Spezifikation. Und, wie Sie festgestellt haben, erzeugt es diese Kuriosität, wobei float explizit in Dezimal konvertiert werden kann und dezimal explizit in float umwandelbar ist, aber da keiner den anderen umfasst, gefällt es dem benutzerdefinierten expliziten Konvertierungscode nicht. Dies ist jedoch eine sehr niedrige Priorität.

    
Eric Lippert 10.05.2010, 22:26
quelle

Tags und Links