为什么使用String.Format?

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

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

我可以看到一些原因:

可读性

 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*/) 

string模板持久性

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

 _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. 

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

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

而你的资源string结束了

英语:“blah blah {0} blah blah {1} blah {2}”

俄语:“{0} blet blet {2} blet {1}”

俄罗斯在处理问题方面可能有不同的规定,因此顺序不同或句子结构不同。

首先,我发现

 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") + "."; 

看看下面是多less维护

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

而不是你必须重复三次的date

其次, String.Format提供的格式说明符给你提供了很大的灵活性,使得string的输出更容易阅读,编写和维护,而不仅仅是使用普通的连接。 另外,使用String.Format更容易获得正确的文化。

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

几个原因:

  1. String.Format()是非常强大的。 您可以在格式string中使用格式提供程序和简单格式指示符(如固定宽度)。
  2. 您可以通过将格式string放在configuration文件中来做一些强大的事情。
  3. String.Format()通常更快,因为它在后台使用StringBuilder和高效的状态机,而.Net中的string连接相对较慢。 随着string的大小和replace值的数量的增加,情况尤其如此。
  4. 对许多程序员来说,String.Format()实际上是比较熟悉的,特别是那些来自使用旧的C printf()函数变体的背景。

最后,别忘了StringBuilder.AppendFormat() 。 String.Format()实际上在后台使用这个方法,直接转到StringBuilder可以给你一种混合的方法:显式地使用.Append()(类似于连接)来处理大string的某些部分,并使用。 AppendFormat()在别人。

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

有关可能的详细信息,我build议阅读MSDN标题复合格式的部分。 它解释了String.Format(以及支持复合格式的xxx.WriteLine和其他方法)与普通级联运算符相比的优点。

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

不过,我个人还是会推荐string.Format除非性能是可读性的关键。

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

比可读性更强

 key + ": " + value 

例如。 还提供了一个很好的关注点分离。 意味着你可以拥有

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

然后将您的键值格式从“{0}:{1}”更改为“{0} – {1}”变成configuration更改,而不是代码更改。

string.Format也有一堆内置的格式,整数,date格式等

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

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

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

哪里

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