做源代码翻译器的过程中有个小插曲,就是对提取出的字符串集合循环做字符串替换时,怎么也替换不掉。当时都有点郁闷了。调试了一个多小时,终于发现字符串替换的动作完全没有了效果。于是在控制台面板上做实验,发现这样一个现象:
string str="测试字符串";
Console.WriteLine(str);
str.replace("测试","Test");
Console.WriteLine(str);
很奇怪的发现,打印结果是
测试字符串
测试字符串
------------------------------------------------------------------------------------------------------------------------------------
当时很想不通,众所周知,C#中的数据类型分引用类型和值类型。两个类型个很明显的区别就是,引用类型使用指针。
比如StringBuilder就是引用类型
StringBuilder str=new StringBuilder("测试字符串");
Console.WriteLine(str);
Str.replace("测试","Test");
Console.WriteLine(str);
打印结果就是
测试字符串
Test字符串
当一个引用类型的变量的内容发生改变的时候,所有用它赋值的变量都会跟着一起变。因为它们实际上是直接指向这个变量的内存地址的。
又比如List<int>集合有5个对象:ABCDE
B=A C=B D=C E=D
当A改变的时候,B,C,D,E都会跟着一起变。
值类型则不同,赋值了,两个变量之间也不会有什么关联。
------------------------------------------------------------------------------------------------------------------------------------
但是String很明显不一样。虽然它是引用类型,但是它的所有操作都在它的副本中进行,操作完后它必须被重新赋值。
同时它的物理地址也变化了,这导致无论它怎么变,引用它的其他变量还是最初的值。
代码应改为:
string str="测试字符串";
Console.WriteLine(str);
str=str.replace("测试","Test");
Console.WriteLine(str);