常见的.net误解 1-1 字符串是不可修改的(immutable)

总是很在很多资料或者文章上介绍.net的字符串是不可以修改的(immutable)

 

 

先来看看什么是字符串

  在.net里面字符串是一个引用类型,但是有很多值类型的特征

  例如比较两个字符串,实际上比较的是两个的内容,而不是引用地址 ,(这里涉及到一个概念就是字符串驻留技术)

 

然后我们看看为什么经常有人说字符串是不可以修改的

  因为字符串有以下特性:

  1. 当你对字符串执行 + ,  Substring 等操作的时候,会返回一个新的字符串,
  2. 一般情况下你找不到可以修改字符串的方法,(直接给他赋值不过是修改一个地址,原来的值并没有变)
  3. 最主要的 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#分类是灰色的  选不了...不知道怎么回事)

posted on 2010-11-12 17:29  听说读写  阅读(1607)  评论(7编辑  收藏  举报

导航