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#中对象的字符串表示形式。
StringBuilder
在需要执行许多串联操作时使用,有助于减少创建的中间字符串的数量。确定是应该使用StringBuilder
普通连接还是普通连接可能并不容易。使用探查器或在堆栈溢出上搜索相关答案。
使用StringBuilder
的主要缺点是使代码难以阅读和维护。对于简单的问题,StringBuilder
这不仅有害于代码的可读性,而且对性能没有用。
string.Join
当您需要添加定界符时,应使用。
显然,永远不要使用string.Join
空的分隔符来连接字符串。
string.Format
当字符串模板优先于字符串连接时可以使用。如kunthet的答案所建议的,您可能更喜欢的一种情况是消息可以本地化。
使用string.Format
有一些缺点,使其不适合像您这样的简单情况:
对于简单的“ {0}”占位符,通常不清楚哪个参数到达哪里。经常会错误地反转参数或忘记一个参数。幸运的是,C#6最终引入了字符串插值来解决此问题。
运行时性能可能会下降。当然,不要以为string.Format
是始终慢。如果性能很重要,请衡量两种方法,然后根据您的实际结果而不是假设来确定哪种方法更快。
该代码编写时间稍长,阅读时间更长,更难维护,尽管这是非常微小的,不应太麻烦。
¹当其中一个物体为时,会出现差异null
。如果不使用ToString
,则将a null
替换为空字符串。使用ToString
,将NullReferenceException
引发a。
a + "" + b + ""
或中"" + a + b + ""
,没关系:全部是字符串连接。在a + b + ""
这非常重要:a
和b
首先加入。