Ich habe diese Funktion:
%Vor% Diese Funktion kann als Func(1,2);
ausgeführt werden. Zeile 1 ist jedoch OK , während Zeile 2 BANG (zur Kompilierzeit) ist.
Die aus Zeile 2 geworfene Ausnahme ist:
Operator '+' kann nicht auf Operanden vom Typ 'T' und 'T'
angewendet werden
Also müssen wir eine Operatorüberladung erstellen. Okay, so weit so gut.
Aber was ist mit Zeile 1? Sollte es nicht auch einen dynamischen Cast auf y
?
((dynamic)x + (dynamic)y);
Ich verstehe, dass es zur Laufzeit ausgewertet wird, aber warum akzeptiert der C # -Compiler den Operator +
in Zeile 1 (d. h. fälschlicherweise davon aus, dass T +
zu etwas anderem sein kann)?
In Ihrem ersten Beispiel haben Sie mit x
a dynamic
die Operation operator+
ebenfalls dynamisch gemacht. Dadurch wird der Typbezeichner T
für x
entfernt, wodurch die Beschwerde, dass T
keine gültige operator+
hat, beseitigt wird.
Zur Laufzeit wird dynamische Bindung auftreten und die beiden Operanden auswerten, um sicherzustellen, dass operator+
verwendet werden kann:
Wenn ein Operand eines arithmetischen Operators den Kompilierzeittyp dynamic hat, wird der Ausdruck dynamisch gebunden (§7.2.2). In diesem Fall ist der Kompilierungszeittyp des Ausdrucks dynamisch, und die unten beschriebene Auflösung wird zur Laufzeit unter Verwendung des Laufzeittyps derjenigen Operanden stattfinden, die den Kompilierungszeittyp dynamic haben.
In Ihrem zweiten Beispiel kennt der Compiler die Typen für x + y
und speichert das Ergebnis einfach in einer Variablen dynamic
. Weitere Verwendungen von result2
werden dynamisch gebunden. Dies ist sinnvoll, da das rechts des Zuweisungsoperators keine dynamischen Operationen enthält:
Wenn keine dynamischen Ausdrücke beteiligt sind, verwendet C # standardmäßig die statische Bindung, was bedeutet, dass die Kompilierungszeitarten der konstituierenden Ausdrücke im Auswahlprozess verwendet werden.
dynamic
sagt dem Compiler im Grunde "versuche nicht, dass das, was ich mache, legal ist; ich bin mir sicher, dass es zur Laufzeit sein wird". Jede Operation, die Sie für eine Variable vom dynamischen Typ versuchen, wird kompiliert. Es wird nur nicht erfolgreich ausgeführt, wenn der der dynamischen Variablen zugewiesene Typ die Operation nicht implementiert.
Um zu erklären, warum beide nicht dynamisch sein müssen, wird der Compiler grundsätzlich versuchen, einen Operator (statische Methode) für jeden der Typen zu finden, die an der Operation beteiligt sind, die der Signatur entspricht, beginnend mit dem LValue. Da der LValue dynamisch ist, muss der Compiler davon ausgehen, dass die Operation für alles existiert, was als X verwendet wird, obwohl X den gleichen Platzhaltertyp wie Y und Y keinen + Operator hat.