32 ビット マネージド アプリケーションを 64 ビットに移植しているときに、構造体内の Equals() オーバーライドによる奇妙な動作を観察しました。
再現ファイルはgithubにあります。
バグを再現するには、「最適化」フラグをオンにしてライブラリをコンパイルする必要があります。これは、リリース構成のデフォルトです。消費する TestApp は、最適化せずにコンパイルする必要があります。64 ビット アプリとして起動するには、Prefer 32 ビットを無効にする必要があります。github の注意事項を参照してください。
ライブラリには、単純なコード行で実装される IEquatable インターフェイスを実装する構造体が含まれています。
public bool Equals(StructWithValue other)
{
return value.Equals(other.value);
}
このコードは、ushort/UInt16 型の Equals メソッドを呼び出します。提案された構成でソリューションをビルドすると、32767 を超える値はすべて失敗します。32768 の ushort 値で Equal を呼び出し、'other' の値も 32768 です。ただし、Equals() は 32767 を超えるすべての値に対して false を返します。
「==」演算子を使用するようにメソッドを変更すると、コードは機能します。また、タイプを構造体からクラスに変更すると、コードは期待どおりに実行されます。
public bool Equals(StructWithValue other)
{
return value == othervalue;
}
これは RyuJIT-Compiler のバグだと思います。従来の JIT コンパイラを使用すると、コードは正常に動作します。
Visual Studio 2015 と TargetFramework 4.6.2 のさまざまな Windows バージョンでテスト済み。