为什么有人在C#和VB .NET中使用String.Format
而不是串联运算符(VB中的&
和C#中的+
)?
主要区别是什么?为什么每个人都对使用String.Format
如此感兴趣?我很好奇。
答案 0 :(得分:390)
我可以看到很多原因:
<强>可读性强>
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 :(得分:90)
除了更容易阅读和添加更多操作符之外,如果您的应用程序是国际化的,这也是有益的。很多时候变量是数字或关键词,对于不同的语言将是不同的顺序。通过使用String.Format,您的代码可以保持不变,而不同的字符串将进入资源文件。所以,代码最终将成为
String.Format(resource.GetString("MyResourceString"), str1, str2, str3);
您的资源字符串最终为
英语:"blah blah {0} blah blah {1} blah {2}"
俄语:"{0} blet blet blet {2} blet {1}"
俄罗斯可能对如何解决问题有不同的规则,因此顺序不同或句子结构不同。
答案 2 :(得分:26)
首先,我找到
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 the Painter problem。
答案 3 :(得分:17)
有几个原因:
String.Format()
非常强大。您可以在格式字符串中使用简单的格式指示符(如固定宽度,货币,字符长度等)。您甚至可以为扩展枚举,将特定输入映射到更复杂的输出或本地化等内容创建自己的格式提供程序。String.Format()
通常更快,因为它在幕后使用StringBuilder
和高效的状态机,而.Net中的字符串连接相对较慢。对于小字符串,差异可以忽略不计,但随着字符串的大小和替换值的数量的增加,它可能会变得明显。String.Format()
对于许多程序员来说更为熟悉,尤其是来自使用旧C printf()
函数变体的背景的程序员。最后,不要忘记StringBuilder.AppendFormat()
。 String.Format()
实际上在幕后使用了这种方法*,直接转到StringBuilder
可以给你一种混合方法:明确地使用.Append()
(类似于连接)的某些部分大字符串,并在其他字符串中使用.AppendFormat()
。
* [edit]原始答案现在已经有8年了,我已经看到了当字符串插值被添加到.Net时可能已经改变的迹象。但是,我还没有回到参考源来验证更改。
答案 4 :(得分:5)
String.Format
还添加了许多选项,包括指定添加到字符串中的每个项目的特定格式的功能。
有关可行内容的详细信息,建议您阅读MSDN上标题为Composite Formatting的部分。它解释了String.Format
(以及xxx.WriteLine
和其他支持复合格式的方法)优于普通连接运算符的优势。
答案 5 :(得分:4)
但是我个人仍然会推荐string.Format
,除非出于可读性原因,性能至关重要。
string.Format("{0}: {1}", key, value);
比
更具可读性key + ": " + value
例如。还提供了一个很好的关注点分离。意味着你可以拥有
string.Format(GetConfigValue("KeyValueFormat"), key, value);
然后将密钥值格式从"{0}: {1}"
更改为"{0} - {1}"
会变为配置更改,而不是代码更改。
string.Format
还内置了一堆格式设置,整数,日期格式等。
答案 6 :(得分:2)
编写像'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。