Когда вызывается оператор Double's ==?
Все началось с вопроса с подвохом, который кто-то задал мне ... (Это упоминается в книге - C # в двух словах) Вот суть этого.
Double a = Double.NaN;
Console.WriteLine(a == a); // => false
Console.WriteLine(a.Equals(a)); // => true
Выше не кажется правильным. a всегда должно быть == для себя (ссылочное равенство) и оба должны быть последовательными.
Похоже, Double перегружает оператор ==. Подтверждено отражателем следующим образом:
[__DynamicallyInvokable]
public static bool operator ==(double left, double right)
{
return (left == right);
}
Странно, что выглядит рекурсивно и без упоминания о специфическом поведении NaN. Так почему же он возвращает false?
Поэтому я добавляю еще немного кода, чтобы различать
var x = "abc";
var y = "xyz";
Console.WriteLine(x == y); // => false
Теперь я вижу
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)
для двойников оператор == переводит вceq
IL-код операциигде, что касается строк, он переводится в System.String :: op_Equality (string, string).Конечно же,документация дляceq
указывает, что это специальный случай для чисел с плавающей запятой и NaN. Это объясняет наблюдения.
Вопросов:
Почему op_Equality определено для Double? (И реализация не учитывает специфическое поведение NaN)Когда это вызывается?