【问题标题】:Why can I pass 1 as a short, but not the int variable i?为什么我可以将 1 作为短变量传递,而不是 int 变量 i?
【发布时间】:2012-07-11 01:29:59
【问题描述】:

为什么第一个和第二个 Write 可以工作,而最后一个不行?有没有一种方法可以允许所有 3 个并检测它是 1、(int)1 还是我传入的?真的为什么允许一个但最后一个?第二个被允许但不是最后一个真的让我大吃一惊。

Demo to show compile error

using System;
class Program
{
    public static void Write(short v) { }
    static void Main(string[] args)
    {
        Write(1);//ok
        Write((int)1);//ok
        int i=1;
        Write(i);//error!?
    }
}

【问题讨论】:

  • 我也被这个难住了,我经常不得不在函数调用中将 int 转换为 short,尽管它们应该是可转换的......
  • @MathieuDumoulin 它们是可施放的,这就是您可以施放它们的原因。但这是一种有损转换(有很多 int 不适合short),所以不可能进行隐式转换,这就是为什么你必须写(short) i

标签: c# compiler-errors int type-conversion implicit-conversion


【解决方案1】:

前两个是常量表达式,最后一个不是。

C# 规范允许将常量从 int 隐式转换为 short,但不适用于其他表达式。这是一个合理的规则,因为对于常量,编译器可以确保值适合目标类型,但对于普通表达式则不能。

这条规则符合隐式转换应该是无损的准则。

6.1.8 隐式常量表达式转换

隐式常量表达式转换允许以下转换:

  • int 类型的常量表达式(§7.18)可以转换为sbytebyteshortushortuint 或@ 类型987654327@,前提是 constant-expression 的值在目标类型的范围内。
  • long 类型的 constant-expression 可以转换为 ulong 类型,前提是 constant-expression 的值不是负数。

(引自 C# 语言规范 3.0 版)

【讨论】:

    【解决方案2】:

    没有从intshort 的隐式转换,因为可能会截断。但是,常量表达式可以被编译器视为目标类型

    1?没问题:这显然是一个有效的short 值。 i?没那么多 - 例如它可能是某个值 > short.MaxValue,而编译器在一般情况下无法检查。

    【讨论】:

    • 所以...不管我有多明确...>_
    • @acidzombie24 你不能。但是你为什么要这样做呢?
    • @acidzombie24 我认为您无法检测到这一点。但是,您可以使用模板参数,然后使用反射来获取其类型。
    • @acidzombie24 在运行时无法传入文字。所以你可以在编译时用眼睛检查。
    • @acidzombie24 在这种情况下,是否可以选择将参数作为Expression<Func<int>> 接受?然后您可以传递() => 1() => i,并在函数内部检查传递的实体是否包含捕获的变量或常量值。
    【解决方案3】:

    int literal 可以隐式转换为 short。鉴于:

    您不能将较大存储大小的非文字数字类型隐式转换为 short

    因此,前两个有效,因为允许对文字进行隐式转换。

    【讨论】:

    • 你的回答有点错误。你不应该使用literal,而应该使用constant-expression。特别是第二个例子不是 literal.
    【解决方案4】:

    我相信这是因为你在前两个中传递了一个文字/常量,但是在第三个中传递一个整数时没有自动类型转换。

    编辑:有人打败了我!

    【讨论】:

      【解决方案5】:

      编译器已经告诉你代码失败的原因:

      cannot convert `int' expression to type `short'
      

      所以这是您应该问的问题:为什么这种转换会失败?我在 Google 上搜索了“c# convert int short”,最后在 MS C# 页面上找到了 short 关键字:

      http://msdn.microsoft.com/en-us/library/ybs77ex4(v=vs.71).aspx

      正如本页所说,从更大的数据类型到 short 的隐式转换只允许用于文字。编译器可以判断文字何时超出范围,但不能,因此需要确保您避免了程序逻辑中的超出范围错误。演员阵容提供了这种保证。

      Write((short)i)
      

      【讨论】:

        【解决方案6】:

        因为在 Nonliteral 类型到更大尺寸的 short 之间不会有任何 隐式 转换。

        隐式转换只能用于常量表达式。

        public static void Write(short v) { }
        

        当您将 integer 值作为参数传递给 short

        int i=1;
        Write(i);  //Which is Nonliteral here
        

        【讨论】:

          【解决方案7】:

          从 int -> short 转换可能会导致数据截断。这就是为什么。

          【讨论】:

            猜你喜欢
            • 2021-09-26
            • 1970-01-01
            • 2022-07-13
            • 1970-01-01
            • 1970-01-01
            • 2011-08-15
            • 2019-12-18
            • 1970-01-01
            • 2019-03-04
            相关资源
            最近更新 更多