在C#中连接字符串和整数变量时,我应该使用.ToString()吗?


19
int a = 1;
int b = 2;
int sum = a + b;
string expression = "Expression: " + a + " + " + b + " = " + sum;
Console.WriteLine(expression); //displays Expression 1 + 2 = 3

我应该使用:

string expression = "Expression: " + a + " + " + b + " = " + sum;

要么

string expression = "Expression: " + a.ToString() + " + " + b.ToString() + " = " + result.ToString();

建议ToString()在连接string和时使用int吗?


6
a + "" + b + ""或中"" + a + b + "",没关系:全部是字符串连接。在a + b + ""这非常重要:ab首先加入。
蒂姆·S.

4
旁注:在VB.NET中,通过使用显式的字符串连接运算符可以避免这种歧义:"Expression: " + a将抛出编译时错误(在Option Strict On情况下),"Expression: " & a将执行字符串连接。
Heinzi 2014年

第一个代码将导致装箱(int到Int32),第二个代码则不会。第二个显然更快。
随机字母

Answers:


33

ToString 用法

不,您不应该ToString在这里使用。

字符串串联会自动将非字符串转换为字符串,这意味着您的两个变体几乎完全相同:

当一个或两个操作数的类型为string时,预定义的加法运算符将操作数的字符串表示形式连接在一起。

来源:C#语言规范:加法运算符MSDN

另一方面,第一个(不带ToString):

  • 写得短些
  • 阅读时间较短,
  • 易于维护,并且:
  • 恰好显示了作者的意图:连接字符串。

所以更喜欢第一个。

引擎盖下

有趣的是看看引擎盖下发生了什么。看到它的一种方式是在LINQPad中观看IL代码。该程序:

void Main()
{
    var a = 3;
    var b = " Hello";
    var c = a + b;
    Console.WriteLine(c);
}

转换为以下IL:

IL_0001:  ldc.i4.3    
IL_0002:  stloc.0     // a
IL_0003:  ldstr       " Hello"
IL_0008:  stloc.1     // b
IL_0009:  ldloc.0     // a
IL_000A:  box         System.Int32
IL_000F:  ldloc.1     // b
IL_0010:  call        System.String.Concat
IL_0015:  stloc.2     // c
IL_0016:  ldloc.2     // c
IL_0017:  call        System.Console.WriteLine

看到了System.String.Concat吗?这意味着原始代码也可以这样编写,从而转换为完全相同的IL:

void Main()
{
    var a = 3;
    var b = " Hello";
    var c = string.Concat(a, b); // This is the line which was changed.
    Console.WriteLine(c);
}

阅读的文档时string.Concat(object[]),您可能会了解到:

该方法通过调用该对象的无参数方法将每个对象串联在args中ToString。它不添加任何定界符。

这意味着ToString多余。也:

String.Empty 用于代替数组中的任何空对象。

这很好地处理了某些操作数为null的情况(请参见脚注1)。

在上一个示例中,将串联转换为string.Concat,还应突出显示编译器优化:

var a = "Hello " + "World";

转换为:

ldstr       "Hello World"
stloc.0

另一方面:

var a = string.Concat("Hello ", "World");

转换为:

ldstr       "Hello "
ldstr       "World"
call        System.String.Concat
stloc.0

其他选择

当然,还有其他方法可以串联C#中对象的字符串表示形式。

  1. StringBuilder在需要执行许多串联操作时使用,有助于减少创建的中间字符串的数量。确定是应该使用StringBuilder普通连接还是普通连接可能并不容易。使用探查器或在堆栈溢出上搜索相关答案。

    使用StringBuilder的主要缺点是使代码难以阅读和维护。对于简单的问题,StringBuilder这不仅有害于代码的可读性,而且对性能没有用。

  2. string.Join 当您需要添加定界符时,应使用。

    显然,永远不要使用string.Join空的分隔符来连接字符串。

  3. string.Format当字符串模板优先于字符串连接时可以使用。如kunthet的答案所建议的,您可能更喜欢的一种情况是消息可以本地化。

    使用string.Format有一些缺点,使其不适合像您这样的简单情况:

    • 对于简单的“ {0}”占位符,通常不清楚哪个参数到达哪里。经常会错误地反转参数或忘记一个参数。幸运的是,C#6最终引入了字符串插值来解决此问题。

    • 运行时性能可能会下降。当然,不要以为string.Format始终慢。如果性能很重要,请衡量两种方法,然后根据您的实际结果而不是假设来确定哪种方法更快。

    • 该代码编写时间稍长,阅读时间更长,更难维护,尽管这是非常微小的,不应太麻烦。


¹当其中一个物体为时,会出现差异null。如果不使用ToString,则将a null替换为空字符串。使用ToString,将NullReferenceException引发a。


1
正是由于这个原因(无法预测的行为),+在大多数语言中将字符串与字符串连接被认为是不良做法。在这种情况下,我会使用string.Concat,在许多情况下string.Format会更好。肯定不是Pythonic的使用+,并且由于%不鼓励使用PEP 3101 str.format
阿尔达·希

2
用一个空字符串代替null真正的“很好地处理它”吗?好吧,这还不如“下一个错误恢复”那么糟糕……
Deduplicator 2015年

在后台,如果不调用.ToString()进行串联,则会发生装箱...,并且Concat(object[])将使用装箱Concat(string[])。所以"string " + i实际上并不等同于"string " + i.ToString()
Random Alphabet

@RandomAlphabets:有效点。但是,不同之处仅在于ToString():在一种情况下OP代码的位置,在另一种情况下OP的代码的位置System.String.Concat。因此,答案仍然有效:不要编写没有好处的代码。
Arseni Mourzenko '17

15

相反,您应该使用字符串格式化程序。将数字格式化为字符串表示形式或本地化会更容易。例如:

string expression = string.Format("Expression: {0} + {1} = {2}", a, b, sum);

有关MSDN的更多信息。

但是,字符串格式化程序比字符串连接的可读性差(也许还有性能)。


6
小心解释为什么这个选项更好?
世界工程师

@WorldEngineer:我更新了解释。
kunthet 2014年

12
我不了解其他所有人,但实际上我觉得这更具可读性。也许是因为我是C语言长大的人,其中s [n] printf是此类代码的唯一现实选择。
Jules 2014年

2
但是这种方式提供了三种错误来源,而不是一种。当您在字符串中添加内容时,您1)必须更改格式字符串,2)不要忘记在列表中添加新参数,3)尝试在列表中选择应放置新参数的正确位置。
Ruslan 2014年

2
只是想了解一下,让您了解C#6中即将推出的字符串插值功能。您将编写“表达式:\ {a} + \ {b} = \ {sum}”以得到相同的结果。codeproject.com/Articles/846566/...
CWAP

-2

如果使用+串联,则它本身使用String.Concat方法。字符串本身不公开+运算符。

例如:

int i = 10;
string str = "hello" + i;

编译成:

int i = 10;
object o1 = "hello";
object o2 = i; // Note boxing
string str = string.Concat(o1, o2);

如果直接调用ToString,它将避免装箱并调用Concat(string, string)重载。因此,ToString尽管效率不高,但通话效率会略高一些。最好使用您觉得更易读的示例。


2
这似乎只是重复先前的回答中提出和解释的观点:“字符串串联会自动将非字符串转换为字符串...”
gnat 2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.