带变量vs内联变量的string.format


9

有什么优点/缺点(如果有)

string output; 
int i = 10;
output = string.Format("the int is {0}", i);

string output; 
int i = 10;
output = "the int is " + i;

我一直使用后一个示例,但似乎大多数在线教程都使用string.format示例。我认为效率没有真正的区别,我最初的想法是使编码人员不必为了插入变量而不断破坏字符串。


8
主要原因是它使翻译变得更加容易,因为您的程序不需要了解不同语言建立句子的方式。例如,与英语翻译相比,许多法语表达和短语是背对背的。
JohnL 2012年

Answers:


22

如果您认为翻译在您的项目中很重要,那么第一种语法确实会有所帮助。

例如,您可能有:

static final string output_en = "{0} is {1} years old.";
static final string output_fr = "{0} a {1} ans.";

int age = 10;
string name = "Henri";
System.out.println(string.Format(output_en, name, age));
System.out.println(string.Format(output_fr, name, age));

另请注意,使用以下语法,您的变量可能不会始终位于句子的同一位置:

static final string output_yoda = "{1} years {0} has.";

4
+1,以使用Yoda说话作为对象-主体-动词语法的示例。
Mike Harris

1
使用C#,我们有一个新的选择:System.out.println($"{name} is {age} year's old.");
Berin Loritsch


@BerinLoritsch:不幸的是,这对于本地化完全不可用。
Bryan Boettcher

@BryanBoettcher,了解,但我在OP中没有看到任何说明他们正在努力完成的事情。
Berin Loritsch

8

查看/programming/4671610/why-use-string-format的第一个答案。在我看来,它涵盖了所有关于它为什么更好的方面。

同样,每个.NET程序集都有一个内部池,其中包含唯一字符串的集合。编译代码时,您在代码中引用的所有字符串文字都会添加到该池中。如果您的代码如下所示:

"the int is " + i + " and the double is " + d

这使得它在池中有2个字符串。

如果你有:

"the int is {0} and the double is {1}"

池中只有一个字符串。

要知道何时对字符串进行内插,以及何时不进行字符串内插,要复杂一点,因为编译器在检测有时可能不需要进行内插的字符串时具有一定的智能...例如,请查看本文该文章提供了对此的更多见解物。

编辑:深入研究之后,我遇到了一个有趣的问题答案,何时使用String.Format与字符串串联比较好?。简而言之,当不涉及本地化时,以+30票的答案的作者提出了令人信服的论点,赞成使用String级联。


2
我也认为,从风格上讲,它会引起人们的共鸣,例如像我这样的人,他们习惯于从c进行printf和sprintf。
乔纳森·亨森

我想知道为什么要拒​​绝投票才能解决我的问题。谢谢。
Jalayn

4

我喜欢第一种方法,因为它可以让我准确地看到输出时字符串的外观。只是添加字符串时,忘记添加空格或添加额外的间距非常容易。

我敢肯定,由于不必创建额外的字符串,因此第一种方法也具有性能优势;但这不是我最关心的。


2

通过使用第一个选项,您可以存储常用的格式字符串并减少键入所需的内容,并使在使用字符串的任何地方都更容易更新字符串。基本上,第一个选项使DRY易于实现。如您所提到的,如果字符串中需要使用多个变量,那么它也是一种更好的语法。


啊,我明白了,我想我没有想到这个例子:string.format(“ int是{0}。再次是{0}”,int);
吉姆(Jim)

1

我认为用string.Format()它可以更容易地看到结果将是什么(因此您不会遇到被遗忘的空格或类似问题的问题),并且键入和修改也更容易。

如果要进行非常简单的格式化,则使用+加号运算符可能会更容易,但是我倾向于仅在连接两个字符串而不是更多时使用它。

为了显示如何string.Format()更轻松地进行修改,请考虑您要在示例中句子的末尾添加句号:从string.Format("The int is {0}", i)string.Format("The int is {0}.", i)只是一个字符。但是,要"the int is " + i实现"the int is " + i + '.'的目标还不止如此。

的另一个优点string.Format()是,它使您可以轻松指定要使用的格式,例如string.Format("The int is 0x{0:X}.", i)。格式化日期时,这一点尤为重要。

至于效率,string.Format()最有可能是较慢的简单字符串连接。但是像这样的代码很可能不会走热,所以没关系。如果这样做的话,使用可能会更好StringBuilder


string.Format仍然在内部使用StringBuilder
Bryan Boettcher

1

使用使您的代码更具可读性的代码。不用担心性能。

对于下面的示例,我更喜欢B,因为它更具可读性。但是上面的语言翻译也很有意义。不要让任何人强迫您使用string.Format,而是阅读并指向Jeff Atwoods的优秀博客,该博客位于Micro Optimizations Theatre的Sad悲剧

A:

string output; 
int i = 10;
output = string.Format("the int is {0}", i);

B:

string output; 
int i = 10;
output = "the int is " + i;

-1

参考:字符串输出:C#中的格式还是concat?

考虑下面的代码。

这是您代码的略微修改版本。

  1. 我删除了Console.WriteLine,因为它可能比我要测量的速度慢几个数量级。
  2. 我在循环前盯着秒表,然后在循环后立即停止它,这样,如果函数需要执行26.4个滴答声,我就不会失去精度。
  3. 用结果除以迭代次数的方法是错误的。看看如果您有1000毫秒和100毫秒,会发生什么情况。在这两种情况下,将其除以1000000都将得到0 ms。
Stopwatch s = new Stopwatch();

var p = new { FirstName = "Bill", LastName = "Gates" };

int n = 1000000;
long fElapsedMilliseconds = 0, fElapsedTicks = 0, cElapsedMilliseconds = 0, cElapsedTicks = 0;

string result;
s.Start();
for (var i = 0; i < n; i++)
    result = (p.FirstName + " " + p.LastName);
s.Stop();
cElapsedMilliseconds = s.ElapsedMilliseconds;
cElapsedTicks = s.ElapsedTicks;
s.Reset();
s.Start();
for (var i = 0; i < n; i++)
    result = string.Format("{0} {1}", p.FirstName, p.LastName);
s.Stop();
fElapsedMilliseconds = s.ElapsedMilliseconds;
fElapsedTicks = s.ElapsedTicks;
s.Reset();


Console.Clear();
Console.WriteLine(n.ToString()+" x result = string.Format(\"{0} {1}\", p.FirstName, p.LastName); took: " + (fElapsedMilliseconds) + "ms - " + (fElapsedTicks) + " ticks");
Console.WriteLine(n.ToString() + " x result = (p.FirstName + \" \" + p.LastName); took: " + (cElapsedMilliseconds) + "ms - " + (cElapsedTicks) + " ticks");
Thread.Sleep(4000);

这些是我的结果:

1000000 x result = string.Format("{0} {1}", p.FirstName, p.LastName); took: 618ms - 2213706 ticks
1000000 x result = (p.FirstName + " " + p.LastName); took: 166ms - 595610 ticks

1
如果第一个代码示例或第二个代码示例是更好的设计,这将如何回答各个方面?1M迭代中超过半秒的代码如何解释一个人是否更容易维护?

吉姆问:“优缺点是什么?” 这表明在许多迭代中,String.Format更快。
jp2code

您应该考虑将其完全添加到答案中,而不是将其保留为代码块以及与OP的代码的区别。就目前而言,您的答案不会用英语回答OP的问题。看看其他答案。可以从中删除所有代码,并且仍然可以回答OP的问题。
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.