C # Expliziter Operator und Objekt

7

FRAGE

Bitte schauen Sie zuerst auf den Code.

Hier ist meine benutzerdefinierte Klasse:

%Vor%

Und hier ist der Testcode, den ich geschrieben habe:

%Vor%

Wie Sie sehen, konnte der Wert nicht konvertiert werden, wenn der Werttyp nicht bekannt ist. Ich glaube, das passiert, weil es in der Objektklasse nach einem Operanden sucht, der nicht reell ist. Wie kann ich dieses Problem lösen?

Ich habe einen Code, bei dem ALLES Objekt ist und es sich um diese Gespräche kümmern muss.

Bitte sagen Sie mir, ob Sie eine Idee haben.

VERMEIDEN VON DYNAMIK

Ok, lass das Sample so ändern, wie du sehen kannst, was ich genau machen möchte und was meine Situation ist.

Hier ist die Klasse, die ich habe:

%Vor%

Und hier ist der Testcode:

%Vor%

Gibt es die Möglichkeit, dass ich die dynamische Klasse von oben her ablegen und weiterarbeiten kann? Ich möchte wirklich .Net4 / 4.5

vermeiden     
Soroush Falahati 17.12.2013, 13:11
quelle

3 Antworten

2

Wie in anderen Antworten angegeben, können Sie dies nicht tun, weil Sie versuchen, das runtime Casting auf Kompilierungszeit Konvertierungsoperationen anzuwenden.

Wenn Sie dynamic vermeiden möchten, weil Sie den DLR von .NET 4.0 nicht verwenden möchten, können Sie die Konvertierungsoperatoren mit Reflection selbst finden. Ich kann die Leistung für Ihre spezielle Anwendung jedoch nicht kommentieren:

%Vor%

Oder für .NET 3.5 mit LINQ:

%Vor%

Verwendung:

%Vor%

Sie können auch "op_Implicit" hinzufügen, wenn Sie über implizite Operatoren konvertieren möchten.

Eine weitere Option, wenn Sie Reflektionen vermeiden möchten, ist die Vorregistrierung der Konvertierungsfunktionen, einige Casting- und Typ-Lookups, um zu bestimmen, welcher Konvertierungsoperator verwendet werden soll.

Nur ein Vorbehalt, die Lösung hier hat ein paar Probleme (Thread-Sicherheit, Annahme, dass Konvertierungsfunktionen existieren, Registrierung Kollidieren / doppelte Konvertierungsfunktionen wirft Fehler) so auf eigene Gefahr verwenden oder verwenden Sie es als Leitfaden zu ändern, wie es passt Ihre Bedürfnisse.

Grundsätzliches besteht darin, einen einfachen Konverter zu definieren, der die Konvertierungsfunktionen selbst umschließt:

%Vor%

Dann ein Dienstprogramm, mit dem Sie diese Konvertierungen registrieren können:

%Vor%

Für die Verwendung müssen Sie zunächst die Konvertierungsfunktionen registrieren, die Sie in Ihrer Anwendung verwenden möchten (idealerweise führen Sie die Registrierung beim Start Ihrer Anwendung durch, um Threading-Probleme zu vermeiden):

%Vor%

Dann Ihre Conversion-Nutzung:

%Vor%

Ich bin mir nicht sicher über die Leistung der einen für die andere Anwendung. Das erste Beispiel ist etwas flexibler, da es die Überprüfung zur Laufzeit durchführt und Sie die zu erwartenden Konvertierungen nicht vorab registrieren müssen. Die zweite könnte etwas stabiler sein, da Sie nur die Conversions registrieren, die Sie erwarten, und es gibt keine Reflektion, nur Casting- und Dictionary-Lookups.

    
Chris Sinclair 17.12.2013, 15:16
quelle
15

Ja, diese zwei sehr unterschiedlichen Dinge. Die erste Zeile:

%Vor%

verwendet den expliziten Konvertierungsoperator, der für diese Kombination überladen ist. Die zweite jedoch:

%Vor%

Dies wandelt den Verweis V als object um (was wir trivialerweise kennen) - und dann separat von object bis Point .

Da Point ein struct ist, versucht dies dann, die gleiche Referenz "auszupacken", als ob es ein eingerahmtes Point wäre. Aber es ist nicht ein eingerahmtes Point , also ist der Fehler korrekt. Konvertierungsoperatoren sind nicht polymorph, und Unboxing ist nur zulässig, wenn die Box eine eingerahmte Kopie des entsprechenden Typs enthält (Vorbehalt: Sie können Enumerationen als Ganzzahlen und Ganzzahlen als Enumerationen aufheben, solange die zugrunde liegenden Typen übereinstimmen).

Aber selbst wenn Point ein class wäre, würde es immer noch mit einem ähnlichen Fehler fehlschlagen: referenzerhaltende Umwandlungen funktionieren auch nicht, wenn die Typen inkompatibel sind.

    
Marc Gravell 17.12.2013 13:16
quelle
2

Es liegt daran, dass Sie es in object umwandeln und Sie keine explizite Umwandlung dafür haben - es wird nicht implizit davon ausgegangen, dass Sie es als float2D haben wollen.

    
Daniel A. White 17.12.2013 13:14
quelle