短的一元减去变成一个int?

rab*_*ble 8 c# int short

在下面的:

public class p
{
  short? mID;
  short? dID;
}

short id = p.mID ?? -p.dID.Value;
Run Code Online (Sandbox Code Playgroud)

编译器给我错误:

错误21无法将类型'int'隐式转换为'short'.存在显式转换(您是否错过了演员?)

我必须将代码更改为以下代码才能工作:

short id = p.mID ?? (short)-p.dID.Value;
Run Code Online (Sandbox Code Playgroud)

好像编译器正在执行类似(int)0 - p.dID.Value,或Int16.operator - 正在返回Int32s ......?

Eri*_*ert 14

我将引用您的规范7.6.2节,其中规定:


对于-x形式的操作,应用一元运算符重载决策来选择特定的运算符实现.操作数转换为所选运算符的参数类型,结果的类型是运算符的返回类型.预定义的否定运算符是:

整数否定:

int operator –(int x);
long operator –(long x);
Run Code Online (Sandbox Code Playgroud)

通过从零减去x来计算结果.如果x的值是操作数类型的最小可表示值(对于int为-2 ^ 31或对于long为-2 ^ 63),那么x的数学否定在操作数类型中是不可表示的.如果在检查的上下文中发生这种情况,则抛出System.OverflowException; 如果它发生在未经检查的上下文中,则结果是操作数的值,并且不报告溢出.如果否定运算符的操作数是uint类型,则将其转换为long类型,并且结果的类型为long.允许将int值-2147483648(-2 ^ 31)写为十进制整数文字的规则是一个例外.

如果否定运算符的操作数是ulong类型,则发生编译时错误.允许将长值-9223372036854775808(-2 ^ 63)写为十进制整数文字的规则是一个例外.

浮点否定:

float operator –(float x);
double operator –(double x);
Run Code Online (Sandbox Code Playgroud)

结果是x的值与其符号反转.如果x是NaN,则结果也是NaN.

十进制否定:

decimal operator –(decimal x);
Run Code Online (Sandbox Code Playgroud)

通过从零减去x来计算结果.十进制否定等效于使用System.Decimal类型的一元减运算符.


如您所见,短裤上没有定义一元减号运算符; 重载决策选择一个整数,因为那个是所有可用的一元减号运算符的最佳匹配.

  • 很好的答案;谢谢!不过,我确实想知道为什么短裤上没有定义一元减运算符。有什么理论吗? (2认同)
  • 对于那些寻找 7.6.2 的人来说,在 ECMA-334 的第 5 版中,该部分似乎已移至 12.8.3。 (2认同)