【问题标题】:Cannot implicitly convert type 'long' to 'int', when it seems no `long` type involved当似乎没有涉及“long”类型时,无法将类型“long”隐式转换为“int”
【发布时间】:2019-04-03 10:57:01
【问题描述】:

另一个帖子跟踪错误Cannot implicitly convert type 'long' to 'int'

public int FindComplement(int num) {
    uint i = 0; 
    uint mask = ~i;

    while((mask&num) != 0) mask <<= 1;
    //return ~mask^num; //<-- error CS0266
    return (int)~mask^num; //<--it works with (int)
}

抱歉问了太多问题,我想知道为什么return ~mask^num会导致类似的错误

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

在我的环境中,return ~mask^num; 会出错,而return (int)~mask^num 可以工作。而且这里似乎没有 long 类型。

【问题讨论】:

  • 因为^是一个长运算符并且还返回long
  • @hotfix ^ 不是长运算符。
  • 相关引述:否则,如果任一操作数为uint类型,而另一操作数为sbyte、short或int类型,则两个操作数都转换为long类型。
  • @hotfix long.operator^ 确实是一个长运算符。例如。 int.operator^ 不是。

标签: c#


【解决方案1】:

您正在尝试使用操作数 intuint 执行 ^ 操作。没有这样的运算符,因此两个操作数都转换为long,并使用long ^(long, long) 运算符。

来自ECMA C# 5 specification,第 12.4.7.1 节:

数值提升包括自动执行某些操作数的隐式转换 预定义的一元和二元数字运算符。数值提升不是一种独特的机制,但 而是将重载决议应用于预定义运算符的效果。数字提升 明确地不影响用户定义的运算符的评估,尽管用户定义的运算符可以是 实施以表现出类似的效果。

从 12.4.7.3 开始:

对于预定义的 +、–、*、/、%、&、|、^、==、!=、>、=、 和

  • ...(此处不适用的规则)
  • 否则,如果任一操作数为 uint 类型,而另一个操作数为 sbyte、short 或 int 类型, 两个操作数都转换为 long 类型。

【讨论】:

  • 感谢详细解释,现在我知道long 类型来自何处。在我下次问问题之前,我可能需要阅读规范。再次感谢 Jon Skeet :)
  • 另一件事是代码可以在没有0U(int) 强制转换的情况下在c++ 中运行良好。 C# 似乎对类型更严格,至少非常不同,对吗?
  • @EricTsui:我已经很久没有使用 C 语言了,但它们在很多方面都是非常不同的语言。
【解决方案2】:

类型 uint 保存从 0 到 4,294,967,295 的数字。这意味着当您使用常规 int 作为参数 num 时,您正在对具有两个不同范围的两种不同类型进行操作。因此,为了不出现此错误,您可以对所有内容使用整数。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-08-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多