字符串插值与String.Format


113

使用字符串插值之间有明显的性能差异:

myString += $"{x:x2}";

vs String.Format()?

myString += String.Format("{0:x2}", x);

我之所以这样问,是因为Resharper会提示您修复问题,而我之前也曾被愚弄过。


4
为什么不尝试两者,看看您是否注意到其中的不同?
Blorgbeard在

57
@Blorgbeard老实说,我很懒。而且我认为,如果你们中的一位正直的男人/女人能立即掌握答案,那将花费更少的时间。
Krythic 2015年

26
我喜欢我第一次问这个问题时,它被否决了,而现在,两年后,这个数字上升到+21。
Krythic

46
说真的 谁能怀疑这个问题的用处?如果每个提出这个问题的人都必须“亲自尝试并看看”,您能想象出整个工作时间的浪费吗?即使只花了5分钟,也可以将其乘以10,000多个到目前为止已经看过这个问题的开发人员。然后,当同事怀疑您的结果时,您会怎么做?再来一次吗?或者,也许只是将他们引荐至此SO帖子。那就是它的用途。
BTownTKD

8
@BTownTKD这是您的典型Stackoverflow行为。如果有人出于预期目的使用该网站,则会立即被疏远。这也是我认为应允许我们集体禁止帐户的原因之一。许多人根本不值得进入该网站。
Krythic

Answers:


72

值得注意的是相对的。但是:字符串插值string.Format()在编译时转换为,因此最终应该得到相同的结果。

但是,它们之间存在细微的差异:正如我们从这个问题可以看出的那样,格式说明符中的字符串串联会导致额外的string.Concat()调用。


4
实际上,在某些情况下(例如,使用a时int),字符串插值可以编译为字符串连接。 var a = "hello"; var b = $"{a} world";编译为字符串连接。var a = "hello"; var b = $"{a} world {1}";编译为字符串格式。
奥马尔·马斯喀特洛

5

字符串插值在编译时转换为string.Format()。

同样在string.Format中,您可以为单个参数指定多个输出,并为单个参数指定不同的输出格式。但是我猜想字符串插值更易读。因此,取决于您。

a = string.Format("Due date is {0:M/d/yy} at {0:h:mm}", someComplexObject.someObject.someProperty);

b = $"Due date is {someComplexObject.someObject.someProperty:M/d/yy} at {someComplexObject.someObject.someProperty:h:mm}";

有一些性能测试结果https://koukia.ca/string-interpolation-vs-string-format-string-concat-and-string-builder-performance-benchmarks-c1dad38032a


2
字符串插值有时只是变成了String::Format。有时进入String::Concat。而且该页面上的性能测试并不是很有意义:您传递给每个方法的参数数量是依赖的。concat并不总是最快的,stringbuilder并不总是最慢的。
Matthias Burger

3

问题是关于性能的,但是标题只是说“ vs”,所以我想不得不再增加一些要点,尽管其中有些是有根据的。

  • 本土化

    • 字符串插值由于其内联代码性质而无法本地化。在本地化之前,它已变成string.Format。但是,有用于此的工具(例如ReSharper)。
  • 可维护性(我的看法)

    • string.Format是更具可读性,因为它专注于句子构造一个很好的和有意义的错误消息时想什么,我的措辞,例如。使用{N}占位符给我更大的灵活性,以后更容易修改它。
    • 另外,在插入过程中的内联格式说明符很容易被误读,并且易于在更改期间与表达式一起删除。
    • 当使用复杂且长的表达式时,插值会很快变得更加难以阅读和维护,因此从这种意义上讲,当代码不断发展且变得更加复杂时,插值无法很好地扩展。string.Format不太容易发生这种情况。
    • 在一天结束的时候它的全部的关注点分离:我不喜欢混合应该如何呈现什么应该被提出

因此,基于这些,我决定坚持使用string.Format大多数代码。但是,我已经准备了一种扩展方法,使我更喜欢一种更流畅的编码方式。该扩展程序的实现是单行的,看起来就像在使用它。

var myErrorMessage = "Value must be less than {0:0.00} for field {1}".FormatWith(maximum, fieldName);

插值是一个很棒的功能,请不要误会我的意思。但是IMO在缺少类似功能的语言中表现最好string.Format,例如JavaScript。


感谢您添加到此。
Krythic

1
我不同意可维护性。授予ReSharper可以使插入的值与其对应的索引匹配起来更加容易(反之亦然),但我认为找出{3}X或Y 还是比较费事,特别是当您开始重新排列格式时。Madlibs例如:$"It was a {adjective} day in {month} when I {didSomething}"VS string.Format("It was a {0} day in {1} when I {2}", adjective, month, didSomething)- > $"I {didSomething} on a {adjective} {month} day"VSstring.Format("I {2} on a {0} {1} day", adjective, month, didSomething)
drzaus

@drzaus感谢您分享您的想法。您的观点很不错,但是只有当我们仅使用简单的,命名合理的局部变量时,这才是正确的。我已经看过很多次了,复杂的表达式,函数调用,插入内插字符串中的任何内容。随着string.Format我觉得你这个问题更容易。但不管怎么说,这就是为什么我强调的是,这是我的看法:)
佐尔坦陶马希
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.