Die Hauptverwirrung besteht darin, dass Sie davon ausgehen, dass alle .NET-Bibliotheken (in diesem Fall die Extended Numerics Library, die nicht Teil der BCL ist) in Standard-C # geschrieben sind. Dies ist nicht immer der Fall und verschiedene Sprachen haben unterschiedliche Regeln.
In Standard-C # würde der angezeigte Code aufgrund der Funktionsweise der Operatorüberlastungsauflösung zu einem Stapelüberlauf führen. Der Code befindet sich jedoch nicht in Standard-C # - er verwendet grundsätzlich undokumentierte Funktionen des C # -Compilers. Anstatt den Operator aufzurufen, wird der folgende Code ausgegeben:
ldarg.0
ldarg.1
ceq
ret
Das war's :) Es gibt keinen 100% äquivalenten C # -Code - dies ist in C # mit Ihrem eigenen Typ einfach nicht möglich .
Selbst dann wird der eigentliche Operator beim Kompilieren von C # -Code nicht verwendet - der Compiler führt eine Reihe von Optimierungen durch, wie in diesem Fall, bei denen der op_Equality
Aufruf nur durch den einfachen ersetzt wird ceq
. Auch hier können Sie dies nicht in Ihrer eigenen DoubleEx
Struktur replizieren - es ist Compiler-Magie.
Dies ist sicherlich keine einzigartige Situation in .NET - es gibt viele ungültige Codes, Standard-C #. Die Gründe sind normalerweise (a) Compiler-Hacks und (b) eine andere Sprache mit den ungeraden (c) Laufzeit-Hacks (ich sehe dich an Nullable
!).
Da der Roslyn C # -Compiler eine Oepn-Quelle ist, kann ich Sie tatsächlich auf den Ort verweisen, an dem die Überlastungsauflösung entschieden wird:
Der Ort, an dem alle Binäroperatoren aufgelöst werden
Die "Verknüpfungen" für intrinsische Operatoren
Wenn Sie sich die Verknüpfungen ansehen, werden Sie feststellen, dass die Gleichheit zwischen double und double zu dem intrinsischen double-Operator führt, niemals zu dem tatsächlichen ==
Operator, der für den Typ definiert ist. Das .NET-Typsystem muss so tun, als wäre Double
es ein Typ wie jeder andere, aber C # nicht - double
ist ein Grundelement in C #.