使用string.Format处理简单的事情?

4
在我刚开始学习 .Net 编程的时候,我只使用 string.Format() 来进行复杂的字符串拼接,例如编译像这样的字符串:

日期为 2/2/2002,付款 ID 为 55543 的客户订单 234 存在问题。

但现在,我几乎在每个需要进行字符串拼接的场景中都使用 string.Format,即使是简单的字符串前缀也是如此。

Console.WriteLine(string.Format("\t\t{0}", myString));

这样做会有可能增加额外负担吗?也许我应该使用常规的+运算符来执行这些简单的操作?

你对此有什么看法?


Console.WriteLine 使用 String.Format 的格式,因此您可以只需执行 Console.WriteLine("\t\t{0}", myString);。@JustinNiessner 在他的答案中也有这个,但已经删除了。 - Jason S
7个回答

5

对于简单的字符串拼接,请使用+方法。对于不需要格式的简单内容,这种方法更清晰。

对于更复杂的字符串,需要一定的格式,并且保留整个字符串的结构并为输入提供占位符,则应使用String.Format

是的,这会增加开销。String.Format在底层使用StringBuilder。在这些情况下,简单的字符串连接将快得多。可以很容易地找到有关此主题的一些基准测试和博客文章。当然,这完全取决于您的使用方式。如果在循环中发生小型字符串连接,则重复使用String.Format可能比直接使用+连接更明显。如果您正在循环中构建一个字符串,则经典示例是首选StringBuilder,并且可以在SO上找到有关连接与 StringBuilder 的相关问题。

编辑: 为了澄清,这样做没有什么用处:String.Format("{0}{1}", a, b),因为没有太多格式。它只是a + b。不幸的是,我在生产代码中遇到过这种情况,只要我看到String.Format,我就期望看到需要以某种方式结构化的内容,而不是直接连接。

另一方面,请考虑以下电话号码:"(" + area + ") " + number + " x" + extension - 这里有太多的内容,并且不容易修改。在这种情况下,最好使用String.Format:String.Format("({0}) {1} x{2}", area, number, extension)。这仍然是一个微不足道的例子,但您可以得到这个想法。


这种代码应该只在I/O操作中使用。I/O操作总是很昂贵的,特别是Console.WriteLine()。解析复合格式字符串的成本是微不足道的,优化它是毫无意义的。 - Hans Passant

2
我通常倾向于在需要合并两个或多个字符串/值的大多数操作中使用string.Format,因为它生成的代码比在中间使用'+'开始和停止字符串更易于阅读。
扩展一下:
string value = string.Format("Hello {0}", user.username);

比起其他方式,这种方法更易读和可扩展。
string value = "Hello" + user.username

例如,如果您想将上次登录日期作为系统升级的一部分添加,您只需扩展代码如下:
string value = string.Format("Hello {0}, you last logged in {1}", user.username, user.lastLogin);

2

对于简单的拼接,使用简单的字符串拼接更加高效。当事情变得更加复杂并且需要使您的代码更易读时,请使用String.Format()

我个人也会这样做(只要我调用的函数没有为我处理格式)。


澄清

对于常规的字符串拼接,例如 "Hello " + "World!";,我会使用 StringBuilder。您的示例通过在输出前添加两个制表符来格式化字符串... 这更像是格式化。

格式化和拼接之间有区别... 要小心您用哪个。


String.Format() 在内部使用 StringBuilder,因此拼接将比普通字符串拼接更高效。

您可能需要更改示例,因为 Console.WriteLine() 可以自己处理格式(不需要使用 String.Format()):

Console.WriteLine("\t\t{0}", myString);


1
你对 StringBuilder 的性能完全误解了。在你的两个示例中,StringBuilder 比字符串拼接要低效得多,你真的不应该将其作为 a + b 等操作的替代品。它又大、又丑、而且效率低下。 - Konrad Rudolph
@Konrad - 确实。我很离谱。快速查看Jon Skeet的博客可以很好地澄清事情:http://www.yoda.arachsys.com/csharp/stringbuilder.html - Justin Niessner

1

我的规则是,如果我需要使用+(连接符)超过一次,我就会将其更改为string.Format

string a = "Something: " + x;   // ok

string b = "Something: " + x + " something else"; // change it to a string.Format
string bB = string.Format("Something: {0} something else", x); // much nicer to read

string c = "Something: " + x + " " + y + " " + z;  // Yuck
string cC = string.Format("Something: {0} {1} {2}", x, y, x);  // Much nicer

0

我不太了解性能方面的问题,可能会有人提供相关数据,但我的感觉是如果你想将格式字符串放在配置文件(或数据库字段或资源文件等)中,那么String.Format是最好的选择。这样,如果你想调整制表符数量、切换到空格、添加分隔符或其他任何操作,都不需要重新编译。


0

我倾向于在仅需要前缀或后缀给定字符串时使用String.Concat而不是String.Format。我更喜欢显式调用Concat方法,而不是使用+运算符,如果您已经使用了String.Format,那么只需要切换一个按键。

IIRC,String.Concat方法将与使用运算符相同,因此它也比String.Format快。


0

我几乎总是使用format,尽管我使用扩展方法而不是静态字符串方法。我发现它更容易理解、更容易改变,通常也更容易维护。它还可以使本地化更容易,因为它不像连接那样引入排序问题。

说实话,哪个看起来更好?

"You have {0} widgets.".Frmt(widgetCount)
"You have " + widgetCount.ToString() + " widgets."

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接