c#中字符串+ = int的不一致行为

时间:2010-08-31 15:51:34

标签: c# linqpad implicit-cast

我正在寻找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'之间没有隐式转换”错误。

3 个答案:

答案 0 :(得分:4)

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

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

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

答案 1 :(得分:2)

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

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

(上面括号中的类型用于说明现有的类型是什么,而不是将它们转换为其他类型。)

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

答案 2 :(得分:2)

+=运算符使用+运算符,因此首先是:

o = o + c;

编译器实际创建的是:

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

整数被装箱,并且调用了带有Concat参数的object方法。将在两个参数上调用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);