为什么使用 String. Format?

为什么会有人在 C # 和 VB 中使用 String.Format。NET 而不是串联运算符(VB 中的 &,C # 中的 +) ?

主要的区别是什么? 为什么每个人都对使用 String.Format这么感兴趣? 我很好奇。

281874 次浏览

除了连接操作符之外,String.Format 还添加了许多选项,包括指定添加到字符串中的每个项的特定格式的能力。

关于可能性的详细信息,我建议阅读关于 MSDN 的题为 复合格式的部分。它解释了 String.Format(以及支持复合格式的 xxx.WriteLine和其他方法)相对于普通连接操作符的优势。

原因有很多:

可读性

string s = string.Format("Hey, {0} it is the {1}st day of {2}.  I feel {3}!", _name, _day, _month, _feeling);

Vs:

string s = "Hey," + _name + " it is the " + _day + "st day of " + _month + ".  I feel " + feeling + "!";

格式说明书 (这包括您可以编写自定义格式化程序的事实)

string s = string.Format("Invoice number: {0:0000}", _invoiceNum);

Vs:

string s = "Invoice Number = " + ("0000" + _invoiceNum).Substr(..... /*can't even be bothered to type it*/)

字符串模板持久性

如果我想在数据库中存储字符串模板怎么办? 使用字符串格式:

_id         _translation
1         Welcome {0} to {1}.  Today is {2}.
2         You have {0} products in your basket.
3         Thank-you for your order.  Your {0} will arrive in {1} working days.

Vs:

_id         _translation
1         Welcome
2         to
3         .  Today is
4         .
5         You have
6         products in your basket.
7         Someone
8         just shoot
9         the developer.

有几个原因:

  1. String.Format()非常强大。您可以在格式字符串中使用简单的格式指示符(如固定宽度、货币、字符长度等)。您甚至可以为诸如扩展枚举、将特定输入映射到更复杂的输出或本地化之类的事情创建自己的格式提供程序。
  2. 通过在配置文件中放置格式字符串,可以实现一些强大的功能。
  3. String.Format()通常更快,因为它在幕后使用 StringBuilder和高效的状态机,而字符串串联在。网速相对较慢。对于较小的字符串,这种差异可以忽略不计,但是随着字符串的大小和替代值的数量增加,这种差异可以引起注意。
  4. 实际上,许多程序员更熟悉 String.Format(),特别是那些来自使用旧的 C printf()函数变体的背景的程序员。

最后,别忘了 StringBuilder.AppendFormat()String.Format()实际上在幕后使用这种方法 * ,直接转到 StringBuilder可以提供一种混合方法: 对大字符串的某些部分显式使用 .Append()(类似于连接) ,在其他部分使用 .AppendFormat()


* [编辑]最初的答案是现在8岁,我已经看到一个迹象,这可能已经改变,当字符串插值被添加到。网。但是,我还没有返回到引用源来验证更改。

首先,我发现

string s = String.Format(
"Your order {0} will be delivered on {1:yyyy-MM-dd}. Your total cost is {2:C}.",
orderNumber,
orderDeliveryDate,
orderCost
);

阅读、编写和维护要比

string s = "Your order " +
orderNumber.ToString() +
" will be delivered on " +
orderDeliveryDate.ToString("yyyy-MM-dd") +
"." +
"Your total cost is " +
orderCost.ToString("C") +
".";

看看下面的代码是多么易于维护

string s = String.Format(
"Year = {0:yyyy}, Month = {0:MM}, Day = {0:dd}",
date
);

你必须重复 date三次。

其次,String.Format提供的格式说明符为字符串的输出提供了很大的灵活性,与仅仅使用普通的旧式串联相比,这种方式更容易读、写和维护。此外,使用 String.Format更容易获得正确的文化关注点。

第三,当性能确实重要时,String.Format的性能将优于串联。在幕后,它使用 StringBuilder并避免使用 画家 Schlemiel 的问题

这个问题的性能方面有一些有趣的东西

然而,我个人仍然推荐 string.Format,除非性能对可读性至关重要。

string.Format("{0}: {1}", key, value);

可读性比

key + ": " + value

比如说,它还提供了一个不错的关注点分离,意味着你可以

string.Format(GetConfigValue("KeyValueFormat"), key, value);

然后将键值格式从 "{0}: {1}"更改为 "{0} - {1}"将变成配置更改而不是代码更改。

string.Format还内置了一系列格式规定,如整数、日期格式等。

除了更容易阅读和添加一些操作符之外,如果您的应用程序是国际化的,这也是有益的。很多时候,变量是数字或关键词,对于不同的语言,它们的顺序是不同的。通过使用 String。格式,当不同的字符串进入资源文件时,代码可以保持不变。所以,代码最终会变成

String.Format(resource.GetString("MyResourceString"), str1, str2, str3);

而您的资源字符串最终是

中文: "blah blah {0} blah blah {1} blah {2}"

俄语: "{0} blet blet blet {2} blet {1}"

俄语可能有不同的规则,如何处理事情,以便顺序不同或句子结构不同。

编写像 'string +"Value"+ string'这样的字符串不可取的一个原因是因为本地化。在发生本地化的情况下,我们希望本地化的字符串被正确格式化,这可能与正在进行编码的语言非常不同。

例如,我们需要用不同的语言显示以下错误:

MessageBox.Show(String.Format(ErrorManager.GetError("PIDV001").Description, proposalvalue.ProposalSource)

哪里

'ErrorCollector.GetError("ERR001").ErrorDescription'返回类似于 "Your ID {0} is not valid"的字符串。此消息必须以多种语言进行本地化。在这种情况下,我们不能在 C # 中使用 + 。我们需要遵循 string.format。