常见的.net误解 1-1 字符串是不可修改的(immutable)
总是很在很多资料或者文章上介绍.net的字符串是不可以修改的(immutable)
先来看看什么是字符串
在.net里面字符串是一个引用类型,但是有很多值类型的特征
例如比较两个字符串,实际上比较的是两个的内容,而不是引用地址 ,(这里涉及到一个概念就是字符串驻留技术)
然后我们看看为什么经常有人说字符串是不可以修改的
因为字符串有以下特性:
- 当你对字符串执行 + , Substring 等操作的时候,会返回一个新的字符串,
- 一般情况下你找不到可以修改字符串的方法,(直接给他赋值不过是修改一个地址,原来的值并没有变)
- 最主要的 c#中的字符串表现出太多值类型的特征
如何修改字符串
参考以下代码:
定义一个指向字符串的指针,根据地址直接修改值
unsafe
{
string s1 = "1 test string";
fixed (char* p = s1)
{
*p = '2';
}
Console.WriteLine(s1);
}
关于字符串驻留
一个字符串一般来说在内存中只有一个实例, 也就是一个字符串是可以同时用在多个地方的
那么修改了一个字符串的内容,其他的字符串也会同时受到影响,参考以下代码: 修改s1的同时 s2也被修改了
unsafe
{
string s1 = "1 test string";
string s2 = "1 test string";
fixed (char* p = s1)
{
*p = '2';
}
Console.WriteLine(s1);
Console.WriteLine(s2);
}
PS1:字符串驻留是一种很有意思的技术,在以后的章节我们可以详细讨论这一点
PS2:直接修改字符串是一个非常危险的行为, 1.他会影响到整个应用程序中用到这个字符串的地方,2.不小心会覆盖到字符串外的其他地方(字符串在内存中的表现形式 之后介绍)
PS3:字符串在内存中的分布形式
.net字符串在内存中由3个部分组成
1. 4B 一个int的值代表这个字符串有多长 (低位在前)
a) 在比较字符串的时候,内部优化的结果就是先比较这个长度, 如果不一样,则立刻返回false ,否则继续检查内容
b)这是一个int值 暗示着在32位系统上 字符串的最大长度就是int的最大值,大约2g
c)如果你要修改的字符串长度改变了原来的长度,例如 "a" -> "a1" ,请记得修改这个值....否则你会发现修改后的字符串断掉了
2. 字符串本身的内容(Unicode-16编码)
3. 4B 字符串结束符(\0) (对于这个问题其实我也有一些疑问, 其实这个在.net中并不重要,其实没有他也一样ok)
未完待续(刚刚开始用博客园....居然发现C#分类是灰色的 选不了...不知道怎么回事)