下面是一个简单的测试夹具。它在调试构建中成功并在发布构建中失败(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 框架使问题消失,但这可能只是侥幸。我发现这种行为有些令人不安,谁能解释为什么编译器会认为进行产生不同可观察行为的优化是安全的?
提前致谢。
最佳答案
此错误已在 this SO question 中出现雅各布·斯坦利。雅各布已经reported the bug ,并且微软已经确认这确实是 CLR JIT 中的一个错误。微软是这样说的:
This bug will be fixed in a future version of the runtime. I'm afraid it's too early to tell if that will be in a service pack or the next major release.
Thank you again for reporting the issue.
您应该能够通过将以下属性添加到 TestChecker()
来解决此错误:
[MethodImpl(MethodImplOptions.NoInlining)]
关于c# - C# 'is' 运算符是否会在 .NET 4 的 Release模式优化下受到影响?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5543692/