60

最近出现了一个关于使用 String.Format() 的问题。我的部分回答包括使用 StringBuilder.AppendLine(string.Format(...)) 的建议。Jon Skeet 认为这是一个不好的例子,并建议使用 AppendLine 和 AppendFormat 的组合。

我突然想到,我从来没有真正让自己适应使用这些方法的“首选”方法。我想我可能会开始使用类似以下的东西,但我很想知道其他人使用什么作为“最佳实践”:

sbuilder.AppendFormat("{0} line", "First").AppendLine();
sbuilder.AppendFormat("{0} line", "Second").AppendLine();

// as opposed to:

sbuilder.AppendLine( String.Format( "{0} line", "First"));
sbuilder.AppendLine( String.Format( "{0} line", "Second"));
4

7 回答 7

65

我认为AppendFormatfollowAppendLine不仅更具可读性,而且比 call 更高效AppendLine(string.Format(...))

后者创建一个全新的字符串,然后将其批量附加到现有的构建器中。我不会说“那为什么还要使用 StringBuilder 呢?” 但这似乎有点违背 StringBuilder 的精神。

于 2008-12-08T14:37:25.377 回答
14

只需创建一个扩展方法。

public static StringBuilder AppendLine(this StringBuilder builder, string format, params object[] args)
{
    builder.AppendFormat(format, args).AppendLine();
    return builder;
}

我喜欢这个的原因:

  • AppendLine(string.Format(...))如上所述,不会遭受与 一样多的开销。
  • 防止我忘记.AppendLine()在最后添加部分(经常发生)。
  • 更具可读性(但这更多是一种观点)。

如果您不喜欢将其称为“AppendLine”,则可以将其更改为“AppendFormattedLine”或任何您想要的名称。不过,我喜欢与其他对“AppendLine”的调用一致的所有内容:

var builder = new StringBuilder();

builder
    .AppendLine("This is a test.")
    .AppendLine("This is a {0}.", "test");

只需为您在 StringBuilder 上使用 AppendFormat 方法的每个重载添加其中一个。

于 2013-09-10T21:41:51.730 回答
11

String.format 在内部创建一个 StringBuilder 对象。通过做

sbuilder.AppendLine( String.Format( "{0} line", "First"));

一个额外的字符串生成器实例,它的所有开销都被创建了。


mscorlib、Commonlauageruntimelibary、System.String.Format 上的反射器

public static string Format(IFormatProvider provider, string format, params object[] args)
{
    if ((format == null) || (args == null))
    {
        throw new ArgumentNullException((format == null) ? "format" : "args");
    }
    StringBuilder builder = new StringBuilder(format.Length + (args.Length * 8));
    builder.AppendFormat(provider, format, args);
    return builder.ToString();
}
于 2008-12-08T18:55:05.420 回答
2

如果性能很重要,请尝试完全避免 AppendFormat()。请改用多个 Append() 或 AppendLine() 调用。这确实使您的代码更大且可读性更低,但它更快,因为不必进行字符串解析。字符串解析比你想象的要慢。

我一般使用:

sbuilder.AppendFormat("{0} line", "First");
sbuilder.AppendLine();
sbuilder.AppendFormat("{0} line", "Second");
sbuilder.AppendLine();

除非性能很关键,否则我会使用:

sbuilder.Append("First");
sbuilder.AppendLine(" line");
sbuilder.Append("Second");
sbuilder.AppendLine(" line");

(当然,如果“First”和“Second”不是字符串文字,这会更有意义)

于 2008-12-08T17:46:22.640 回答
0

AppendFormat() 比 AppendLine(String.Format()) 更具可读性

于 2008-12-08T14:37:37.343 回答
0

我更喜欢这种结构:

sbuilder.AppendFormat("{0} line\n", "First");

虽然不可否认,要分离换行符有一些话要说。

于 2008-12-08T14:49:47.617 回答
0

简单地使用真的很糟糕吗

sbuilder.AppendFormat("{0} line\n", first);

? 我的意思是,我知道它不是独立于平台或其他什么的,但在 10 个案例中有 9 个可以完成工作。

于 2008-12-08T14:53:15.253 回答