为什么引用类型string的行为却是值类型

为什么引用类型string的行为却是值类型       

        分类:            C# 64人阅读 评论(0) 收藏 举报
首先,我们需要知道string的如下特性:

1.字符串做参数,传递的是引用,只是一个指针的复制,你修改参数的指向,影响不到调用它的函数中的那个指针所指向的内容
2.字符串不可修改。你以任何一种形式修改了字符串(+,=等操作),源字符串其实还在的,只是根据你的修改重新生成了一个新的字符串
3.如果需要修改,两种方案,一是将修改后的字符串返回;二是作参数传字符串时使用 ref 传递,这样子函数中可以直接修改掉主函数中的指针指向,从而指向新的字符串。
4  定义字符串时,会先查CLR内部的散列表。

  字符串类型就是一个值类型的引用类型,用c++的概念来解释的话,就是一个指针,即*pstr.
  
  *pstr = "123"; ----string中存放的是地址
  
  但是c#中做了特殊的处理,就是第2条,不能对修改pstr所指向的地址的值。当你修改*pstr的值时,其实c#并没有修改pstr所
  指的内存的值,而是重新分配了一块内存赋新的值,然后再将这块新的内存的首地址赋值给指针pstr. 正是因为这条奇怪的规  则,使得c#中的引用类型的string的行为却是值类型。

 
  对于第1条,字符串做参数时,其实就相当于c++中的指针做参数,*pstr,这样传递的都是地址。但是因为第2条的原则规则,函数内用传入的指针*pstr_input去修改值后,pstr_input指向了修改后的值的内存,而原始指针pstr还是指向原来的内存,pstr指向的内存的值和pstr_input指向的内存的值当然就不一样了。

 
  对于第3条, 当用 ref string 来传递参数时,其实就是相当于c++中的 **point指针的指针的方式了,这样传递参数的时候,参数中就是原始参数*pstr指针pstr的指针,即传递的值就是&pstr. 这样在函数中修改string时就会修改string的引用值,即修改*point的值。因为是用**point这样的指针的指针的方式,函数中的对*point的修改时可以带出去的。即函数中的修改,等于需改了主函数中的指针指向,函数中与主函数中都同时指向新的字符串。

  对于第4条,
  string str1 = "string"; string str2 = "string"; Console.WriteLine(string.ReferenceEquals(str1, str2));
  既然String类型是引用类型,那么代码一输出的应该是False,然而事实上代码一输出时的是True。这是因为当CLR初始化的时  ,它会创建一个内部的散列表,Key为字符串,Value为指向托管堆中字符串对象的引用。当构造str1时,先会去散列表中查询  是否存在”string”字符串,如果不存在那么会在托管堆中构造一个新的String对象,然后将”string”字符串和指向该对象的引  用添加到散列表中,当构造str2时,由于散列表中存在Key为”string”的引用,于是将Value值赋值给str2,那么str1和str2引  用的是同一个String对象,代码一自然就返回True了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值