C# 中字符串不变时字符串的可变性

Mutability of string when string doesn't change in C#

如果字符串操作不改变字符串的值,那最终会创建一个新实例吗?

例如,

string str = "foo";
str += "";

我知道 C# 中 string 和 StringBuilder 的区别。

不,不是。您可以使用 object.ReferenceEquals() 简单地测试它,如下所示:

        string s = "test";
        string q = s;
        s += "";
        bool eq1 = object.ReferenceEquals(s, q); //--> References are equal
        s += "1";
        bool eq2 = object.ReferenceEquals(s, q); //--> References are not equal any more 

String.Concat(string,string),这通常是编译器将字符串 'addition' 转换成的内容,检查其中一个参数是否为 null 或空,并且 returns非 NullOrEmpty 参数。因此,在您的示例中,它将只是 return str,并且不会创建任何对象。

但实际上,compiler may optimize away your entire operation 注意到您只是连接了一个空字符串。更好的测试是两个值都是变量,其中一个恰好包含一个空字符串。

不会,只有当字符串操作改变了字符串变量中的值时,才会创建新的实例。

可以用ObjectIDGenerator class. It's worth reading this complete article来证明

using System;
using System.Text;
using System.Runtime.Serialization;

namespace StringVsStringBuilder
{
    class Program
    {
        static void Main(string[] args)
        {
            ObjectIDGenerator idGenerator = new ObjectIDGenerator();
            bool blStatus = new bool();
            // blStatus indicates whether the instance is new or not
            string str = "Fashion Fades,Style Remains Same";
            Console.WriteLine("Initial state");
            Console.WriteLine("str = {0}", str);
            Console.WriteLine("Instance id: {0}", idGenerator.GetId(str, out blStatus));
            Console.WriteLine("This is new instance: {0}", blStatus);
            // A series of operations that won't change value of str
            str += "";

            // Try to replace character 'x' which is not present in str so no change
            str = str.Replace('x', 'Q');

            // Trim removes whitespaces from both ends so no change
            str = str.Trim();
            str = str.Trim();
            Console.WriteLine("\nFinal state");
            Console.WriteLine("str = {0}", str);
            Console.WriteLine("Instance id: {0}", idGenerator.GetId(str, out blStatus));
            Console.WriteLine("This is new instance: {0}", blStatus);
            Console.ReadKey();
        }
    }
}