La confusion principale ici est que vous êtes en supposant que tous les .Bibliothèques NET (dans ce cas, l'extension d'objets Numériques de la Bibliothèque, qui n'est pas une partie de la BCL) sont écrits en C# standard. Ce n'est pas toujours le cas, et dans des langues différentes des règles différentes.
Dans la norme C#, le morceau de code que vous voyez seraient le résultat d'un débordement de la pile, en raison de la façon dont l'opérateur de résolution de surcharge fonctionne. Toutefois, le code n'est pas vraiment dans la norme C# - il utilise essentiellement des sans-papiers caractéristiques du compilateur C#. Au lieu d'appeler l'opérateur, il émet ce code:
ldarg.0
ldarg.1
ceq
ret
C'est tout :) Il n'y a pas de 100% équivalent en code C# - ce n'est tout simplement pas possible en C# avec votre propre type.
Même alors, le réel de l'opérateur n'est pas utilisé lors de la compilation de code C# - le compilateur ne un tas d'optimisations, comme dans ce cas, où il remplace l' op_Equality
appel avec la simple ceq
. Encore une fois, vous ne pouvez pas reproduire cela dans votre propre DoubleEx
struct - il le compilateur de la magie.
Ce n'est certainement pas une situation unique dans .NET - il y a beaucoup de code n'est pas valide, la norme C#. Les raisons sont généralement (a) compilateur hacks et (b) une autre langue, à l'étrange (c) exécution des hacks (je suis à la recherche à vous, Nullable
!).
Depuis le Roslyn compilateur C# est oepn source, je peux effectivement vous pointer à l'endroit où la résolution de surcharge est décidé:
Le lieu où tous les opérateurs binaires sont résolus
Les "raccourcis" pour intrinsèques des opérateurs
Quand vous regardez les raccourcis, vous verrez que l'égalité entre le double et le double des résultats de la valeur intrinsèque du double de l'opérateur, jamais dans le réel ==
défini par l'opérateur sur le type. L' .NET type de système est de prétendre qu' Double
est un type comme les autres, mais le C# n'est pas - double
est une primitive en C#.