演员表和强类型作业之间有区别吗?

时间:2014-03-24 14:55:19

标签: c# types compiler-construction

今天我写了一些代码时遇到了这种情况。以下面的例子为例:

long valueCast  = (long)(10 + intVariable);
long valueTyped = 10L + intVariable;

这两者之间有什么区别,还是编译成完全相同的东西?一个人的约定是否超过另一个?

所以我知道这不是一个关键问题(两者都有效)。我很好奇这些差异可能是什么!

编辑 - 修改了代码示例,使其更接近原始场景的实际情况。我希望问题清楚,所以我用常量替换了变量。没有意识到编译器会自动运算(从而改变这个问题的答案)

3 个答案:

答案 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在实际操作之前被转换为很长时间