今天我写了一些代码时遇到了这种情况。以下面的例子为例:
long valueCast = (long)(10 + intVariable);
long valueTyped = 10L + intVariable;
这两者之间有什么区别,还是编译成完全相同的东西?一个人的约定是否超过另一个?
所以我知道这不是一个关键问题(两者都有效)。我很好奇这些差异可能是什么!
编辑 - 修改了代码示例,使其更接近原始场景的实际情况。我希望问题清楚,所以我用常量替换了变量。没有意识到编译器会自动运算(从而改变这个问题的答案)
答案 0 :(得分:39)
是的,这两者之间存在很大差异。不适用于那些特定值,但具有不同值的完全相同的表达式将显示差异。
在第一个版本中,添加以32位算术完成,然后结果转换为long
。
在第二个版本中,第一个操作数已经是long
,因此第二个操作数被提升为long
,然后以64位算术执行加法。
当然在这种情况下,编译器无论如何都会执行算术本身(并且在两种情况下得出相同的结论),但理解转换结果之间的区别非常重要。操作的一部分,并转换操作的操作数之一。
举个例子:
unchecked
{
long valueCast = (long)(2000000000 + 2000000000);
long valueTyped = 2000000000L + 2000000000;
Console.WriteLine(valueCast);
Console.WriteLine(valueTyped);
}
结果:
-294967296
4000000000
请注意,这必须在明确未经检查的上下文中完成,否则第一次添加甚至不会编译 - 您将收到" CS0220的错误:操作在编译时以检查模式溢出"。
答案 1 :(得分:7)
嗯,这是一个编译错误:
long valueCast = (long)(2147483647 + 2);
“在检查模式下,编译时操作溢出。”
虽然这样可以正常工作:
long valueTyped = (2147483647L + 2);
正如Jon Skeet所说,不同之处在于你在做总和之前或之后是否转换为long
。
答案 2 :(得分:2)
在你的例子中,10L + 2;等于((长)10)+ 2;
这与(长)(10 + 2)不同,因为:
(long)(10 + 2)操作以int(32bit)执行,然后转换为long(64bit)
((长)10)+ 2;操作执行为长(64位),因为10在实际操作之前被转换为很长时间