以下は簡単なテストフィクスチャです。デバッグ ビルドでは成功し、リリース ビルドでは失敗します (VS2010、.NET4 ソリューション、x64):
[TestFixture]
public sealed class Test
{
[Test]
public void TestChecker()
{
var checker = new Checker();
Assert.That(checker.IsDateTime(DateTime.Now), Is.True);
}
}
public class Checker
{
public bool IsDateTime(object o)
{
return o is DateTime;
}
}
コードの最適化が大混乱を引き起こしているようです。リリース ビルドで無効にすると、同様に機能します。それは私にとってかなり不可解でした。以下では、ILDASM を使用してビルドの 2 つのバージョンを逆アセンブルしました。
IL をデバッグします。
.method public hidebysig instance bool IsDateTime(object o) cil managed
{
// Code size 15 (0xf)
.maxstack 2
.locals init (bool V_0)
IL_0000: nop
IL_0001: ldarg.1
IL_0002: isinst [mscorlib]System.DateTime
IL_0007: ldnull
IL_0008: cgt.un
IL_000a: stloc.0
IL_000b: br.s IL_000d
IL_000d: ldloc.0
IL_000e: ret
} // end of method Validator::IsValid
リリース IL:
.method public hidebysig instance bool IsDateTime(object o) cil managed
{
// Code size 10 (0xa)
.maxstack 8
IL_0000: ldarg.1
IL_0001: isinst [mscorlib]System.DateTime
IL_0006: ldnull
IL_0007: cgt.un
IL_0009: ret
} // end of method Validator::IsValid
ストアとロードが最適化されているようです。以前のバージョンの .NET フレームワークをターゲットにすることで問題は解決しましたが、それはまぐれかもしれません。私はこの動作がやや不安であることがわかりました.コンパイラが、異なる観察可能な動作を生成する最適化を行うことが安全であると考える理由を誰か説明できますか?
前もって感謝します。