【问题标题】:Strings and ints, implicit and explicit字符串和整数,隐式和显式
【发布时间】:2010-10-05 18:50:52
【问题描述】:

有一个同事问我这个问题,在我头脑混乱的状态下我没有答案:

为什么你可以这样做:

string ham = "ham " + 4;

但不是:

string ham = 4;

如果在连接时存在字符串转换的隐式转换/操作,为什么在分配它作为字符串时不一样? (当然不用做一些运算符重载)

【问题讨论】:

    标签: c# string int implicit explicit


    【解决方案1】:

    第一个表达式右边的值是一个字符串,而第二个表达式右边的值不是。连接在第一个场景中提供了魔力,其中任务没有做任何特别的事情。在第二种情况下,作业继续装傻。

    【讨论】:

      【解决方案2】:

      当连接编译器将语句"ham" + 4 转换为对String.Concat 的调用,它接受两个object 参数,因此值4 被装箱,然后调用ToString

      对于赋值,没有从intstring 的隐式转换,因此您不能在不显式转换的情况下将4 分配给string

      换句话说,编译器对这两个赋值的处理方式非常不同,尽管它们在 C# 中看起来非常相似。

      【讨论】:

      • 实际上是真的,但我不知道它实际上是调用Concat方法还是生成等效代码。参考似乎表明后者。
      • 如果您使用 Reflector 查看发布模式代码(将其设置为显示 IL),您会发现它确实调用了 Concat。
      • 现在终于明白为什么我不经常在 razor 中看到 ToString() 调用了。我一直认为这是剃刀代码的一些特殊约定。
      【解决方案3】:

      进行连接时没有隐式转换。字符串连接解析为 String.Concat 调用,该调用具有接受对象的重载。正是这个重载执行了(显式)到字符串的转换。

      【讨论】:

        【解决方案4】:

        表达式

        "ham " + 4 
        

        根据字符串类型和加法运算符的组合,强制将 4 隐式转换为字符串。具体来说,它是“+”运算符的一种特性,在进行运算符重载时,您可以手动实现相同类型的东西。

        一个类似但不太明显的例子是:

        long myNumber = Int64.MaxValue - 1;

        在这种情况下,“1”应该被评估为一个 32 位整数,但它是隐式转换的。您可以查看 C# 语言规范第 6.1 节以获取编译器支持的隐式转换的详尽列表。

        编辑:要清楚,我提到的语言规范部分列出了编译器支持的隐式转换,而像“+”这样的运算符可以有自己支持的转换。

        【讨论】:

        • int 到字符串没有隐式转换。
        • 没错。有一个与“+”运算符相关的隐式转换。
        • 没有为字符串定义 + 运算符。编译器会生成对 Concat 的相应调用。
        【解决方案5】:

        二进制 + 运算符预定义为 数字和字符串类型。对于数字 类型,+ 计算其两个的总和 操作数。当一个或两个操作数 是字符串类型,+ 连接 的字符串表示 操作数。

        Reference

        赋值运算符 (=) 存储 其右手操作数的值 存储位置、财产或索引器 由它的左操作数表示,并且 返回值作为其结果。这 操作数必须是同一类型(或 右手操作数必须是 隐式转换为 左边的操作数)。

        Reference

        【讨论】:

          猜你喜欢
          • 2014-11-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-07-26
          • 1970-01-01
          • 2023-03-24
          • 1970-01-01
          • 2012-04-25
          相关资源
          最近更新 更多