【问题标题】:Unary minus on a short becomes an int?短的一元减号变成一个整数?
【发布时间】:2011-01-04 17:12:16
【问题描述】:

如下:

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

short id = p.mID ?? -p.dID.Value;

编译器给了我错误:

错误 21 无法将类型“int”隐式转换为“short”。存在显式转换(您是否缺少演员表?)

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

short id = p.mID ?? (short)-p.dID.Value;

就好像编译器正在执行 (int)0 - p.dID.Value 之类的操作,或者 Int16.operator - 正在返回 Int32s...?

【问题讨论】:

    标签: c# int short


    【解决方案1】:

    请参阅规范的第 7.6.2 节,其中指出:


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

    整数否定:

    int operator –(int x);
    long operator –(long x);
    

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

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

    浮点求反:

    float operator –(float x);
    double operator –(double x);
    

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

    十进制否定:

    decimal operator –(decimal x);
    

    结果是通过从零中减去 x 来计算的。小数取反等价于使用 System.Decimal 类型的一元减号运算符。


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

    【讨论】:

    • 很好的答案;谢谢!不过,我确实想知道为什么没有在短裤上定义一元减号运算符。有什么理论吗?
    • @rabidpebble 当然,对于(所有?)二元运算符也是如此。例如p.mID + p.mIDp.mID / p.mIDp.mID & p.mID 和许多其他都将具有int 类型,即使两个操作数都是shorts。
    • 对于那些寻找 7.6.2 的人来说,在 ECMA-334 的第 5 版中,该部分似乎已移至 12.8.3。
    【解决方案2】:

    没有采用短值的一元减号运算符。相反,重载决议选择一元减号运算符的 int 版本并进行隐式转换。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-02
      • 1970-01-01
      • 2019-10-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多