Мы столкнулись с магическим десятичным числом, которое нарушило нашу хеш-таблицу. Я свел его к следующему минимальному случаю:
decimal d0 = 295.50000000000000000000000000m;
decimal d1 = 295.5m;
Console.WriteLine("{0} == {1} : {2}", d0, d1, (d0 == d1));
Console.WriteLine("0x{0:X8} == 0x{1:X8} : {2}", d0.GetHashCode(), d1.GetHashCode()
, (d0.GetHashCode() == d1.GetHashCode()));
Получение следующего вывода:
295.50000000000000000000000000 == 295.5 : True
0xBF8D880F == 0x40727800 : False
Что на самом деле своеобразно: измените, добавьте или удалите любую из цифр в d0, и проблема исчезнет. Даже добавление или удаление одного из завершающих нулей! Знак, похоже, не имеет значения.
Наше решение состоит в том, чтобы разделить значение на избавьтесь от завершающих нулей, например:
decimal d0 = 295.50000000000000000000000000m / 1.000000000000000000000000000000000m;
Но у меня вопрос, почему C # делает это неправильно?
edit: Просто заметил, что это было исправлено в .NET Core 3.0 (возможно, раньше, я не делал этого) не проверяю): https://dotnetfiddle.net/4jqYos