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

dre*_*w_w 17 c# compiler-construction types

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

long valueCast  = (long)(10 + intVariable);
long valueTyped = 10L + intVariable;
Run Code Online (Sandbox Code Playgroud)

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

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

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

Jon*_*eet 39

是的,这两者之间有很大的不同.不适用于那些特定值,但具有不同值的完全相同的表达式将显示差异.

在第一个版本中,添加是在32位算术中完成的,然后将结果转换为a long.

在第二个版本中,第一个操作数已经是a long,因此第二个操作数被提升为,long然后以64位算术执行加法.

当然,在这种情况下,编译器无论如何都将执行算术本身(并且在两种情况下都得出相同的结论),但是理解转换操作结果和转换操作的一个操作之间的区别很重要.

举个例子:

unchecked
{
    long valueCast  = (long)(2000000000 + 2000000000);
    long valueTyped = 2000000000L + 2000000000;
    Console.WriteLine(valueCast);
    Console.WriteLine(valueTyped);
}
Run Code Online (Sandbox Code Playgroud)

结果:

-294967296
4000000000
Run Code Online (Sandbox Code Playgroud)

请注意,这必须在显式未经检查的上下文中完成,否则第一次添加甚至不会编译 - 您将收到"CS0220:在编译模式下编译时操作溢出"的错误.

  • @Areks:是的,*那些*是等价的......当然后者允许你表达32位范围之外的常数. (3认同)
  • 谢谢Jon!我看着你的答案正在构建并从头开始投票,我觉得我现在可以死而没有遗憾! (2认同)

Tim*_*man 7

好吧,这是一个编译错误:

long valueCast = (long)(2147483647 + 2);
Run Code Online (Sandbox Code Playgroud)

"在检查模式下,操作在编译时溢出."

虽然这很好用:

long valueTyped = (2147483647L + 2);
Run Code Online (Sandbox Code Playgroud)

正如Jon Skeet所说,不同之处在于你是在转换long之前还是之后转换.

  • 当然,Jon编辑的内容基本上和我输入答案的例子相同.:) (4认同)