【问题标题】:Using string.Format for simple things?将 string.Format 用于简单的事情?
【发布时间】:2011-01-29 12:26:58
【问题描述】:

在我早期的 .Net 编程时代,我仅将 string.Format() 用于复杂的字符串连接,例如将字符串编译为

2002 年 2 月 2 日的客户订单 234 和付款 ID 55543 存在问题。

但现在我几乎对我必须做的每一个字符串连接都使用了 string.Format,还有一些简单的连接,比如在字符串前面加上一些东西。

Console.WriteLine(string.Format("\t\t{0}", myString));

这有什么可能的开销吗?也许我应该使用常规的+ 运算符来完成这些简单的操作?

您对此有何看法?

【问题讨论】:

  • Console.WriteLine 使用String.Format 的格式,所以你可以做Console.WriteLine("\t\t{0}", myString); @JustinNiessner 在他的回答中有这个,但把它擦掉了。

标签: .net string-formatting string-concatenation


【解决方案1】:

对于简单的字符串连接,使用+ 方法。对于不需要格式的简单事物,它更清晰。

对于具有特定格式的更复杂的字符串以及保留整个字符串的结构并为输入提供占位符很有用的地方,请使用String.Format

是的,有开销。 String.Format 在幕后使用 StringBuilder。在这些情况下,简单的字符串连接会快得多。可以很容易地找到有关此主题的一些基准测试和博客文章。当然,这一切都取决于您的使用情况。如果循环中出现小字符串连接,那么重复使用 String.Format 可能会比简单的 + 连接更明显。如果您要在循环中构建 large 字符串,那么经典示例是首选StringBuilder,有关 concat 与 StringBuilder 的相关问题可以在 SO 上找到。

编辑:澄清一下,这没什么用:String.Format("{0}{1}", a, b),因为没有太多的格式。这只是a + b。不幸的是,我在生产代码中遇到过这样的例子,当我看到 String.Format 时,我希望看到需要以某种方式构造的东西,而不是简单的连接。

OTOH,考虑一下这个电话号码:"(" + area + ") " + number + " x" + extension - 发生的事情太多了,而且不容易修改。在这种情况下,最好使用 String.Format:String.Format("({0}) {1} x{2}", area, number, extension)。这仍然是一个微不足道的例子,但你明白了。

【讨论】:

  • 这种代码只能用于 I/O 操作。 I/O 总是很昂贵,尤其是 Console.WriteLine()。解析复合格式化字符串的成本可以忽略不计,优化它毫无意义。
【解决方案2】:

我也倾向于在大多数需要组合两个或多个字符串/值的操作中使用 string.Format,因为它比在中间用 + 开始和停止字符串更容易阅读代码。

展开

string value = string.Format("Hello {0}", user.username);

更具可读性和可扩展性
string value = "Hello" + user.username

例如,如果您想将上次登录日期添加为系统升级,您可以简单地将代码扩展为以下内容

string value = string.Format("Hello {0}, you last logged in {1}", user.username, user.lastLogin);

【讨论】:

    【解决方案3】:

    简单的连接对于简单的事情更有效。当事情变得更复杂时使用String.Format(),它使您的代码更易于阅读。

    我个人做同样的事情(只要我调用的函数不为我处理格式)。


    澄清

    对于像"Hello " + "World!"; 这样的常规字符串连接,我会使用StringBuilder。您的示例通过添加两个选项卡来格式化输出字符串……我认为这更像是格式化。

    格式化和连接之间是有区别的...小心你使用什么。


    String.Format() 在内部使用 StringBuilder,因此连接将比进行常规字符串连接更有效。

    您可能想要更改您的示例,因为 Console.WriteLine() 可以自己处理格式设置(不需要 String.Format()):

    Console.WriteLine("\t\t{0}", myString);
    

    【讨论】:

    • 您对StringBuilder 的性能还差得很远。在您的示例中,StringBuilder 的效率低于字符串连接,并且您真的不应该使用它来替代 a + b 之类的东西。它又大又丑而且效率低。
    • @Konrad - 确实。我很离谱。快速浏览一下 Jon Skeet 的博客可以很好地解决问题:yoda.arachsys.com/csharp/stringbuilder.html
    【解决方案4】:

    我的规则是,如果我必须多次使用+(连接),我将其更改为string.Format

    string a = "Something: " + x;   // ok
    
    string b = "Something: " + x + " something else"; // change it to a string.Format
    string bB = string.Format("Something: {0} something else", x); // much nicer to read
    
    string c = "Something: " + x + " " + y + " " + z;  // Yuck
    string cC = string.Format("Something: {0} {1} {2}", x, y, x);  // Much nicer
    

    【讨论】:

      【解决方案5】:

      我不知道性能,有人可能会提供该数据,但我的感觉是,如果您想将格式字符串放入配置文件(或数据库字段或资源文件)中,String.Format 是一种方法管他呢)。这样,如果您想调整制表符的数量、切换到空格、添加分隔符等,您不必重新编译。

      【讨论】:

        【解决方案6】:

        当我只需要给给定字符串添加前缀或后缀时,我倾向于使用String.Concat 而不是String.Format。我更喜欢显式调用 Concat 方法,然后使用 + 运算符,如果您已经在使用 String.Format,只需切换一个按键即可。

        IIRC,String.Concat 方法将与使用运算符相同,因此它也比String.Format 更快。

        【讨论】:

          【解决方案7】:

          我几乎总是使用格式,尽管我使用扩展方法而不是静态字符串方法。我发现它更容易理解,更容易改变,而且通常更容易维护。它还可以使本地化更容易,因为它不会像串联那样引入排序问题。

          老实说,哪个更好看?

          "You have {0} widgets.".Frmt(widgetCount)
          "You have " + widgetCount.ToString() + " widgets."
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2023-02-07
            • 1970-01-01
            • 1970-01-01
            • 2015-11-28
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多