【问题标题】:inconsistent behavior with string+=int in c#c# 中与 string+=int 不一致的行为
【发布时间】:2010-08-31 15:51:34
【问题描述】:

我正在查看 LINQPad 中的一些代码高尔夫,想知道为什么:

int c;
string o;

o+=c;//this works

o+=P==2?"."+c:c;//this doesn't

o+=P==2?"."+c:""+c;//this does

主要是为什么第一个有效,而第二个会引发“'string' 和 'int' 之间没有隐式转换”错误。

【问题讨论】:

    标签: c# linqpad implicit-conversion


    【解决方案1】:

    字符串上的+ 运算符可以接受一个int,从而产生另一个字符串。但是,没有从 int 到 string 的隐式(或显式)强制转换。

    当您使用三元运算符?: 时,两个“分支”必须是相同类型,或者一个类型必须可以隐式转换为另一个。

    在你的第二个例子中,第一个分支是一个字符串,在 + 运算符完成之后,但第二个只是一个 int,所以它不起作用。在您的第三个示例中,两个分支都是字符串,所以没关系。

    【讨论】:

    • 所以要获得第二个工作答案,请输入:o+=P==2?"."+c:c.ToString();
    【解决方案2】:

    您的第二个无效示例在 ?: 运算符中具有不一致的类型。你所拥有的是:

    o += (P == 2 ? (string) "." + c : (int) c);
    

    (上面括号中的类型是为了阐明现有类型是什么,而不是将它们转换为不同的类型。)

    三元运算符中:的两边必须是同一类型。因此,您的第二个示例是语法错误。第三个示例有效,因为与空字符串连接会将c 强制转换为字符串。

    【讨论】:

    • 啊,谢谢。我没有意识到双方必须是同一类型。不过,这是有道理的。我还不能接受答案,请稍等。
    • 没有你说的那么严格。必须有从结果到备选类型的转换,或者从备选到结果类型的转换。 (但是,如果它们不同,则不是两者都不同。)这里的行为很微妙。对于其中一些微妙之处,请参阅我关于该主题的文章:blogs.msdn.com/b/ericlippert/archive/tags/conditional+operator
    【解决方案3】:

    += 运算符使用+ 运算符,所以第一个是真的:

    o = o + c;
    

    编译器实际创建的是:

    o = String.Concat((object)o, (object)c);
    

    整数被装箱,并调用带有object参数的Concat方法。 ToString 方法将在两个参数上调用以获取它们的字符串值,并将它们连接起来。

    如果首先将整数转换为字符串,代码会更直接:

    o += c.ToString();
    

    变成:

    o = String.Concat(o, c.ToString());
    

    在第二个代码中,条件运算符中的类型不匹配:

    bool ? string : int
    

    第二个和第三个操作数必须具有相同的类型,就像在第三个代码中一样:

    bool ? string : string
    

    第二个代码真的变成了:

    o = String.Concat(
      o,
      P == 2
        ? String.Concat((object)".", (object)c)
        : c
    );
    

    第三个代码真的变成了:

    o = String.Concat(
      o,
      P == 2
        ? String.Concat((object)".", (object)c)
        : String.Concat((object)String.Empty, (object)c)
    );
    

    无论如何,您应该考虑使用StringBuilder 来构建字符串,而不是使用+= 运算符:

    StringBuilder builder = new StringBuilder;
    
    if (P == 2) {
      builder.Append('.');
    }
    builder.Append(c);
    

    【讨论】:

    • 它在一些代码高尔夫中,所以目标是让它使用尽可能少的字符。我知道它在运行时不是最有效的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-28
    • 1970-01-01
    • 1970-01-01
    • 2012-11-14
    相关资源
    最近更新 更多