"Prove" 该字符串在 C# 中是不可变的

"Prove" that string is immutable in c#

我已经知道在 C# 中,字符串是引用类型,大多数情况下都像值类型一样处理,但我最近发现了这一点: http://net-informations.com/faq/general/immutable.htm

我正在尝试 "prove" 字符串是不可变的,方法是在发生连接时打印对字符串变量的引用:

string s = string.Empty;
for (int i = 0; i < 10; i++)
{
    s += " " + i;
    // Console.WriteLine(&s);
}

如您所料,如果该行未注释,则代码不会编译(编译器错误 CS0208:无法获取托管类型的地址、获取其大小或声明指向托管类型的指针('type')).

我也尝试了 GetHashCode(),但显然对于字符串,它 return 是基于...字符串值本身的相同值(即它总是 return 相同的结果例如“0”)。

有办法吗?它不会用于编码目的,只是为了理解目的......如果不是,你怎么知道它会 "really" 在每次连接时创建 n 个字符串实例?来自 "knowing it"...

编辑:可能不是 C# memory address and variable 的副本,因为我想知道如何获取引用类型的地址,显然该线程只处理值类型。

如果要检查是否创建了新实例,只需将其与之前的实例进行比较即可:

string s = string.Empty;
for (int i = 0; i < 10; i++)
{
    var saved = s;
    s += " " + i;
    if (ReferenceEquals(saved, s))
        Console.WriteLine("oops, no new instance created?");
}

你会看到这不会打印任何东西。

您可以使用ObjectIDGenerator为字符串生成id,看看id是否相同。

var string1 = "Jerry";
ObjectIDGenerator generator = new ObjectIDGenerator();
bool string1FirstTime;
long string1Id = generator.GetId(string1, out string1FirstTime);


bool string2FirstTime;
var string2 = string1 + " Seinfeld";
long string2Id = generator.GetId(string2, out string2FirstTime);

下面将 return 错误,因为它们不相同。

var same = string1Id == string2Id;

可以将字符串复制到另一个变量中,比较修改前后的引用和值:

string s = string.Empty;
for (int i = 0; i < 10; i++)
{
    var copy = s;

    // true
    Console.WriteLine("both are the same reference: {0}", Object.ReferenceEquals(s, copy));
    // true
    Console.WriteLine("both are the same value: {0}", s.Equals(copy));

    s += " " + i;

    // false
    Console.WriteLine("both are the same reference: {0}", Object.ReferenceEquals(s, copy));
    // false
    Console.WriteLine("both are the same value: {0}", s.Equals(copy));
}