我做了以下投地double,并回long,故意:
var adjustedValue = (long)(double)dateTime.Ticks;
Run Code Online (Sandbox Code Playgroud)
(dateTimea System.DateTime和Ticksa 在哪里long).然而Resharper告诉我,演员double是"多余的",这让我想知道它是否可以被编译器优化掉.
我在LINQPad中尝试了这段代码:
var dateTime = DateTime.Now;
var adjustedValue = (long)(double)dateTime.Ticks;
adjustedValue.Dump();
Run Code Online (Sandbox Code Playgroud)
无论是否优化,它都会生成相同的IL(唯一的区别在于标签):
IL_0000: call System.DateTime.get_Now
IL_0005: stloc.0 // dateTime
IL_0006: ldloca.s 00 // dateTime
IL_0008: call System.DateTime.get_Ticks
IL_000D: conv.r8
IL_000E: conv.i8
IL_000F: stloc.1 // adjustedValue
IL_0010: ldloc.1 // adjustedValue
IL_0011: call LINQPad.Extensions.Dump
Run Code Online (Sandbox Code Playgroud)
所以答案是否定的,C#编译器没有优化这个双重演员.即使启用了优化,转换仍然存在.
但是,您还应该注意到,此双重转换会显着改变原始数据.这是一个使用LINQPad创建的快速演示:
var dateTime = DateTime.Now;
var originalValue = dateTime.Ticks;
var adjustedValue = (long)(double)originalValue;
originalValue.Dump(); // 635385353415288655
adjustedValue.Dump(); // 635385353415288704
Run Code Online (Sandbox Code Playgroud)
这是因为double只有15-16位精度,但a long可能长达19位.你一定会得到一些舍入错误.如果这是一个问题,您可以使用decimal替代.这样可以避免任何舍入错误,但即使在这种情况下,C#编译器也不会对双重转换进行优化.
当然,JIT编译器或NGen.exe如何将其转换为本机代码是完全不同的事情,但我希望行为是相同的.