C# 中的四种字符串连接方式的内部原理

在 C# 中,字符串连接操作我们可以使用 operator +string.Concat 的方式,也可以使用 string.FormatStringBuilder,这四种方式有什么区别呢。

static void Main(string[] args)
{
    string s1 = "hello";
    string s2 = "world";

    string helloworld1 = s1 + s2;
    string helloworld2 = string.Concat(s2, s2);

    string helloworld3 = string.Format("{0}{1}", s1, s2);

    StringBuilder sb = new StringBuilder();
    sb.Append(s1);
    sb.Append(s2);
    string helloworld4 = sb.ToString();

}

查看 CIL 即可知道,s1 + s2; 实质是调用的是 string.Concat。我们可以查看微软开源的 .net string 源码 ,你会发现 string.Concat 是创建一个新的 string 对象,然后把 s1 和 s2 拷贝到这个新对象中。

String result = FastAllocateString(str0Length + str1.Length);
FillStringChecked(result, 0,  str0);
FillStringChecked(result, str0Length, str1);
return result;

string.Format内部实现是基于StringBuilder, 其核心代码如下。其中 StringBuilderCache 是有缓存机制的StringBuilder,也就是说多次调用string.Format有可能只需要实例化一个StringBuilder,当然这个缓存是有命中率的,如果字符串太大,仍然会实例化一个新的StringBuilder

private static String FormatHelper(IFormatProvider provider, String format, ParamsArray args)
{
    if (format == null)
        throw new ArgumentNullException("format");

    return StringBuilderCache.GetStringAndRelease(
        StringBuilderCache
            .Acquire(format.Length + args.Length * 8)
            .AppendFormatHelper(provider, format, args));
}

综上,我们探讨了四种字符串连接操作的内部原理,在实践中请合理选择。