Quando o operador Double == é chamado?

Tudo começou com uma pergunta complicada que alguém fez para mim .. (É mencionado no livro - C # em poucas palavras) Aqui está a essência disso.

Double a = Double.NaN;
Console.WriteLine(a == a); // => false
Console.WriteLine(a.Equals(a)); // => true

O acima não parece certo. a deve sempre ser == para si mesmo (igualdade de referência) e ambos devem ser consistentes.

Parece que o Double sobrecarrega o operador ==. Confirmado pelo refletor da seguinte forma:

[__DynamicallyInvokable]
public static bool operator ==(double left, double right)
{
    return (left == right);
}

Estranho que parece recursivo e nenhuma menção ao comportamento específico do NaN. Então, por que isso retorna falso?

Então eu adiciono mais um código para distinguir

var x = "abc";
var y = "xyz";
Console.WriteLine(x == y); // => false

Agora eu vejo

    L_0001: ldc.r8 NaN
    L_000a: stloc.0 
    L_000b: ldloc.0 
    L_000c: ldloc.0 
    L_000d: ceq 
    L_000f: call void [mscorlib]System.Console::WriteLine(bool)
    L_0014: nop 
    L_0015: ldloca.s a
    L_0017: ldloc.0 
    L_0018: call instance bool [mscorlib]System.Double::Equals(float64)
    L_001d: call void [mscorlib]System.Console::WriteLine(bool)
    L_0022: nop 
    L_0023: ldstr "abc"
    L_0028: stloc.1 
    L_0029: ldstr "xyz"
    L_002e: stloc.2 
    L_002f: ldloc.1 
    L_0030: ldloc.2 
    L_0031: call bool [mscorlib]System.String::op_Equality(string, string)
    L_0036: call void [mscorlib]System.Console::WriteLine(bool)
para duplas, a chamada telefônica == se traduz emceq IL opcodeonde, como para strings, é traduzido como System.String :: op_Equality (string, string).

Com certeza odocumentação paraceq especifica que é especial para números de ponto flutuante e NaN. Isso explica as observações.

Questões:

Por que a op_Equality é definida em Double? (E a implementação não leva em conta o comportamento específico do NaN)Quando é invocado?

questionAnswers(3)

yourAnswerToTheQuestion