【问题标题】:When do you use StringBuilder.AppendLine/string.Format vs. StringBuilder.AppendFormat?您何时使用 StringBuilder.AppendLine/string.Format 与 StringBuilder.AppendFormat?
【发布时间】:2008-12-08 14:32:18
【问题描述】:

最近的question came up 关于使用 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"));

【问题讨论】:

  • 也许您的代码示例可以说明这两种情况? :)

标签: c# .net formatting stringbuilder


【解决方案1】:

我认为AppendFormat 后跟AppendLine 不仅更易读,而且比调用AppendLine(string.Format(...)) 更高效。

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

【讨论】:

  • 是的,我会完全接受这个(顺便说一句,感谢您首先接受我)。
  • 没问题 - 如果我的语气在原始评论中显得粗鲁,我很抱歉。多任务处理有时对我来说是这样的:(
【解决方案2】:

只需创建一个扩展方法。

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 方法的每个重载添加其中一个。

【讨论】:

    【解决方案3】:

    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();
    }
    

    【讨论】:

      【解决方案4】:

      如果性能很重要,请尽量避免使用 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”不是字符串文字,这会更有意义)

      【讨论】:

      • 我所做的基准测试显示,当使用单独的 Append() 调用而不是使用 4 个参数的单个 AppendFormat() 调用时,性能提高了 5 倍。
      【解决方案5】:

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

      【讨论】:

        【解决方案6】:

        我更喜欢这种结构:

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

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

        【讨论】:

        • 我倾向于使用\r\n,但我更喜欢Environment.NewLine,它使用起来很尴尬。因此提出这个问题。
        【解决方案7】:

        简单地使用真的很糟糕吗

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

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-12-29
          • 2014-01-23
          • 2019-07-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多