Der entsprechende Abschnitt der C# Spezifikation ist
Der Abschnitt ist langwierig, aber es destillieren dazu: Sie eine explizite Konvertierung mit (Foo)doub
definieren, und da Wenn Sie eine explizite Konvertierung verwenden, wählt der Compiler die spezifischsten verfügbaren Conversions aus, einschließlich Conversions, die ausschließlich explizit sind, um die Zwischenschritte bei der Conversion durchzuführen Pfad (wenn sie verfügbar sind).
Wenn U enthält genau einen benutzerdefinierten Umwandlungsoperator die von SX zu TX umwandelt, dann ist dies die spezifische Umwandlung Operator. Wenn kein solcher Operator vorhanden ist oder wenn mehr als ein solcher Operator vorhanden ist, ist die Konvertierung nicht eindeutig und es tritt ein Kompilierungszeitfehler auf. Andernfalls wird die benutzerdefinierte Konvertierung angewendet:
Wenn S nicht SX ist, wird eine explizite Standardkonvertierung von S nach SX durchgeführt.
Der spezifischste benutzerdefinierte Konvertierungsoperator wird aufgerufen, um von SX in TX zu konvertieren.
Wenn TX nicht T ist, wird eine explizite Standardkonvertierung von TX nach T durchgeführt.
(Hervorhebung von mir)
Hier S
ist die Quelle Typ und T
ist der Zieltyp, während SX
ist der spezifische Quelle Typ in dem expliziten Betreiber des Zieltypen definiert (das heißt, Foo
) und TX
ist der spezifischste Zieltyp, der in den expliziten Operatoren T
definiert ist.
Hier existiert eine explizite Umwandlung von double
zu int
und es daher als die am besten geeignete gewählt wird aus der Quelle Argumenttyp (double -- S
) mit dem Eingang Argumenttyp des expliziten Operator (int -- SX
) zu konvertieren. Es muss nicht explizit sein, da Sie bereits ausdrücklich die Konvertierung in Foo
vorgenommen haben.
Dies funktioniert nur, weil es keine zweideutigen Alternativen gibt. Wenn Sie Foo
definiert haben:
struct Foo
{
public int value;
public uint uvalue;
public static explicit operator Foo(int val)
{
return new Foo { value = val };
}
public static explicit operator Foo(uint val)
{
return new Foo { uvalue = val };
}
}
dies zum Beispiel erzeugt ein Fehler bei der Kompilierung (mit dem gleichen Main
) von:
Fehler 1 Mehrdeutige benutzerdefinierte Konvertierungen ‚Foo.expliziten Operator Foo (uint)‘und 'Foo.explicit Operator Foo (int) double 'auf '
Again' Foo', wenn aus der Umwandlung', das durch das Buch ist (gemäß dem ersten Absatz oben zitierten) seit Die Menge der verfügbaren Konvertierungen U
enthält jetzt zwei gleichwertige explizite Konvertierungen und der Compiler kann nicht entscheiden, ob Sie die int
Konvertierung oder die uint
Konvertierung aufrufen möchten. Im ersten Beispiel gibt es nur einmal Auswahl, und es ist klar, so dass der Compiler es nimmt.
das ist explizit. Wenn Sie versuchen, impliziten Operator Foo (int val) 'Sie werden sehen, dass Sie nicht schreiben können' Foo foo = double; '... –
@ M.kazemAkhgary Dieser Code verursacht Fehler. http://ideone.com/ttBLLX Aber mit 'öffentlichen statischen impliziten Operator Foo (int val)' 'Foo a = (Foo) double;' funktioniert – Alex78191
Die gegebenen Antworten sind gut. Weitere Informationen finden Sie unter https://blogs.msdn.microsoft.com/ericlippert/2007/04/16/chained-user-defined-explicit-conversions-in-c/ und https://blogs.msdn.microsoft.com/ericlippert/2007/04/18/verkettete-benutzerdefiniert-explizite-conversions-in-c-teil-two/und https://blogs.msdn.microsoft.com/ericlippert/2007/04/20/chained- user-defined-explicit-conversions-in-c-teil-three/ –