При портировании 32-битного управляемого приложения на 64-битное я наблюдал странное поведение с помощью переопределения Equals() внутри структуры.
Вы найдете репрограмму в github.
Чтобы воспроизвести ошибку, вы должны скомпилировать библиотеку с флагом "optimize". Это значение по умолчанию находится в конфигурационном файле Release. Потребляемый TestApp должен быть скомпилирован без какой-либо оптимизации. Предпочтение 32 бит должен быть отключен для запуска в виде 64-битного приложения. См. Примечания по github!
Библиотека содержит структуру, которая реализует интерфейс IEquatable, который реализован с помощью простой строки кода.
public bool Equals(StructWithValue other)
{
return value.Equals(other.value);
}
Этот код вызывает метод Equals типа ushort/UInt16. Если вы построите решение с предлагаемой конфигурацией, все значения выше 32767 потерпят неудачу. Вы вызываете Equal на значение usrort 32768, а значение "other" равно 32768. Но Equals() вернет false для всех значений выше 32767.
Если вы измените метод использования оператора '==', код будет работать. Также, если вы измените тип от struct к классу, код будет работать как ожидалось.
public bool Equals(StructWithValue other)
{
return value == othervalue;
}
Я думаю, что это ошибка в компиляторе RyuJIT. Если я использую устаревший JIT-компилятор, код работает нормально.
Протестировано с Visual Studio 2015 и TargetFramework 4.6.2 в разных версиях Windows.