为什么要使用String.Format?

Mat*_*zen 168 c# vb.net

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

主要区别是什么?为什么每个人都如此感兴趣String.Format?我很好奇.

Moo*_*ice 396

我可以看到很多原因:

可读性

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

VS:

string s = "Hey," + _name + " it is the " + _day + "st day of " + _month + ".  I feel " + feeling + "!";
Run Code Online (Sandbox Code Playgroud)

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

string s = string.Format("Invoice number: {0:0000}", _invoiceNum);
Run Code Online (Sandbox Code Playgroud)

VS:

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

字符串模板持久性

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

_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.
Run Code Online (Sandbox Code Playgroud)

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.
Run Code Online (Sandbox Code Playgroud)

  • +1的人为`有人只是拍摄开发者.;-) (196认同)
  • 我不了解你,但我读了没有格式化的那个.特别是当我想知道究竟发生了什么时,我必须在文本和参数之间来回切换,这甚至不计算错误计数和错误的可能性(这可能不是一个问题,参数更少,但是去超过10,它不再有趣).正如Ashley指出的那样,如果使用ToString方法中构建的格式,则第二个点为null.我同意第三个,但我不认为我会在特定情况之外使用它. (28认同)
  • 对于'substr'示例,您应该使用_invoiceNum.ToString("00000").ToString支持与string.Format()相同的复合格式设置当您只有一个要格式化的值时,ToString()通常比Format()更简单/更清晰. (13认同)
  • @ppumkin那不是真的.当你在一个表达式中指定了特定数量的+运算符时,编译器将把它转换为对`string.Concat`的单个调用,并且不会创建任何中间字符串.使用StringBuilder实际上*会伤害*性能,而不是帮助它,因为Concat可以从一开始就创建一个完全正确大小的内部缓冲区.当您有某种循环或其他控制块时,使用SB,以便编译器在编译时不知道正在连接的字符串数. (10认同)
  • +1 - 同样使用`String.Format`更快,使用更少的开销.使用concat` +`/`&`每次都要重建字符串,这在大型字符串对象中可能非常糟糕.`string`的定义是它应该被定义一次并重复使用多次.(很多书教我们使用concat作为例子,但从不告诉我们性能!!)构建字符串应该使用`StringBuilder`,它甚至更快比`String.Format`!非常好的答案 - 开发人员需要学习编写可读代码并记住性能! (8认同)
  • 我不认为通过从代码中删除字符串模板而提供的关注点分离不应被低估.如果一些不好的措辞成为问题,这可能意味着简单的配置更改或数据库更新与完整的紧急更改之间的区别. (2认同)
  • 您的可读性示例确实看起来像是一个明确的胜利......对于concat方法.为什么我要_want_必须扫描参数的精确顺序以确定哪一个去哪里? (2认同)
  • 我还想在这里提一下C#现在支持字符串插值,它具有string.format的优点,但由于对变量和函数的内联评估,它提供了更短的语法并且更易于阅读.http://www.dotnetperls.com/string-interpolation.我建议你在string.format上使用它. (2认同)

doo*_*bop 91

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

String.Format(resource.GetString("MyResourceString"), str1, str2, str3);
Run Code Online (Sandbox Code Playgroud)

虽然你的资源字符串最终成为了

英语: "blah blah {0} blah blah {1} blah {2}"

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

俄罗斯可能对如何处理事情有不同的规则,因此顺序不同或句子结构不同.

  • +1在我看到这个之前,我从未考虑过String.Format的本地化应用程序. (6认同)

jas*_*son 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
);
Run Code Online (Sandbox Code Playgroud)

比阅读,编写和维护更容易

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

看看以下是多么可维护

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

在替代方案中你必须重复date三次.

其次,提供的格式说明符String.Format使您能够以比使用普通旧级联更容易阅读,编写和维护的方式为字符串输出提供极大的灵活性.此外,更容易理解文化问题String.Format.

第三,当性能确实重要时,String.Format将胜过连接.在幕后它使用了一个StringBuilder并避免施莱米尔画家的问题.


Joe*_*orn 17

几个原因:

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

最后,别忘了StringBuilder.AppendFormat(). String.Format()实际上在幕后使用这种方法*,StringBuilder直接进入可以给你一种混合方法:明确地.Append()对大字符串的某些部分使用(类似于连接),并.AppendFormat()在其他部分使用.


*[edit]原始答案现在已经有8年了,而且我已经看到了当字符串插值被添加到.Net时可能已经改变的迹象.但是,我还没有回到参考源来验证更改.

  • 参考#3:字符串构建器并不比连接快.它的神话是由"测试"支持,它实际上在不同的行(或循环)中进行连接.当所有串联在一行上完成时,编译器将其转换为string.append(paramaarray)调用,这是所有选项中最有效的.在string.append调用期间,目标字符串的确切大小是提前知道的,可以立即分配,每个字符只复制一次. (6认同)
  • `string.Format`通常不会比几个字符串连接快,因为格式字符串也需要被解析和复制. (3认同)

Ree*_*sey 5

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

有关可能的详细信息,我建议您阅读MSDN上标题为" 复合格式 "的部分.它解释了String.Format(以及xxx.WriteLine支持复合格式化的其他方法)优于普通连接运算符的优点.

  • 字符串格式很好,但是比连接慢。说够了。 (2认同)