为什么我添加了2个短片导致由于整数引起的转换编译错误?

Kal*_*exx 3 c# casting

在我的代码中,我有以下代码:

Order = config.DeploymentSteps.Select(x => x.Order).DefaultIfEmpty().Max() + 1;
Run Code Online (Sandbox Code Playgroud)

这给了我错误Cannot implicitly convert type 'int' to 'short'.作为参考Order,x.Order并且都是短裤,并Max()正确返回short(我已经验证了这一点).所以我明白了,它认为这1是一个integer错误的.所以我改成了:

Order = config.DeploymentSteps.Select(x => x.Order).DefaultIfEmpty().Max() + (short)1;
Run Code Online (Sandbox Code Playgroud)

我现在仍然得到相同的编译.所以也许它不是正确的,所以我尝试将它改为

Order = config.DeploymentSteps.Select(x => x.Order).DefaultIfEmpty().Max() + Convert.ToInt16(1);
Run Code Online (Sandbox Code Playgroud)

但我仍然得到同样的错误.最后我通过转换整个表达式来实现它:

Order = Convert.ToInt16(config.DeploymentSteps.Select(x => x.Order).DefaultIfEmpty().Max() + 1);
Run Code Online (Sandbox Code Playgroud)

为什么我不能将1转换为a short并将其添加到另一个short中,而不是将整个东西抛出来?

kev*_*v22 5

这是因为short + short = int.

Eric Lippert 在这里解释道.

他说:

为什么短而短的结果是int?

好吧,假设空头和空头很短,看看会发生什么:

short [] price = {10000,15000,11000}; 短期平均=(价格[0] +价格[1] +价格[2])/ 3; 当然,如果这个计算是短暂的,那么平均值是-9845.总和大于最大可能的短,所以它包围负数,然后你除负数.

在整数运算环绕的世界中,在int中进行所有计算更为明智,这种类型可能具有足够的范围以使典型计算不溢出.

  • @Hans:我看不出可用的IL操作与任何事情有什么关系.没有用于将两位小数加在一起的IL操作码,但我们在C#中高兴地允许这样做.没有用于可空算术的IL操作码,我们也乐意允许这样做.C#语义的设计考虑了C#用户的典型用例场景,而不是可用的操作码.如果可能有很多C#用户做短线算术,我们就确保在短路上有内置运算符,而不管我们必须生成什么IL,就像我们用十进制做的那样. (6认同)
  • @Eric:如果你是那种对短裤进行算术运算的人,那么你可能会首先使用整数.同样正确.这不是编译器是一个忙碌的身体压倒愚蠢的程序员,事实是没有办法添加两个短裤,你不能为它生成代码.它*可以*选择如何处理不适合的结果. (3认同)
  • 嗯,并没有真正解释为什么int + int = int而且不长.真正的原因是CLI只允许在Opcodes.Add指令上使用有限数量的类型.Int,long,float,double和IntPtr.必要时必须提升操作数以使它们匹配.C#语言设计者*做了*决定不将结果静默地截断回更小的类型.与vb.net设计师不同. (2认同)
  • @Hans:当然,性能是设计中的一个因素.默认情况下,C#在很大程度上选择了未经检查的32位算术,因为在大多数芯片上,*jitted代码*很快,不是因为碰巧有IL指令.我只是没有遵循你的论点,即C#语义是由可用的操作码驱动的.请记住,我们都在同一个部门; 如果早期的C#设计师觉得我们需要一个IL操作码来添加两个短路,那么CLR会有这样的操作码! (2认同)