日期:2014-05-18  浏览次数:20468 次

关于值类型和引用类型最基础的问题
书上说:

对于引用类型,两个变量可能引用同一个对象,因此对一个变量的操作可能影响到另一个变量所引用的对象。
对于值类型,每个变量都有自己的数据副本,对一个变量的操作不可能影响到另一个变量。

string   name1   =   "张学友 ";
Response.Write(name   +   " <br   /> ");
string   name2   =   name1;
Response.Write(sex   +   " <br   /> ");
name   =   "刘德华 ";
Response.Write(name1   +   " <br   /> ");
Response.Write(name1   +   " <br   /> ");

int   i   =   1;
Response.Write(i   +   " <br   /> ");
int   j   =   i;
Response.Write(j   +   " <br   /> ");
i   =   2;
Response.Write(i   +   " <br   /> ");
Response.Write(j   +   " <br   /> ");

为什么上面运行出来的值类型和引用类型的结果会是一致的,不太明白,高手能否给出代码详细讲解下上面两句话。

------解决方案--------------------
string 是特殊的引用类型
string name1 = "张学友 ";
string name2 = name1;
name1 = "刘德华 "; //也会复制副本
----------------------------------
.net的string内存管理机制不太清楚,
delphi的话你可以参考string类型的引用计数
------解决方案--------------------
string 是一种特殊的引用类型,因为该类型在程序中使用量大大多于其他类型,而且经常会在多个不同的线程中使用相同的字符串,因此在.Net中string进行了特殊的处理,那就是string对象在托管内存中一直都是“不可变”的,任何对string的修改操作都将导致新创建一个新的string,然后把对原来那个string的引用转到新创建的string上,如:


string s = "aaa "; //假设s变量在托管内存中从 0x00000001 开始

/* 下面这句语句并不是修改s所引用的0x0000001内存区域的值,因为string是不可变的,这句语句实际上在另外一个(假设0x0010001)位置开辟一个空间存 "bbb "这个值,然后把原来指向0x00000001的s的引用修改到0x0010001上面来 */
s= "bbb ";


所以上面的结果就可以解释了,当
string name2 = name1;
时,name2和name1指向相同的托管内存位置,但是在你执行
name2 = "刘德华 ";
的时候,name2就指向了新为 "刘德华 "开辟的新的内存空间,因此输出了你所说的结果。

------解决方案--------------------
如果你要验证这一过程,可以用unsafe 代码,用指针指向这个name2的位置(不要fixed)

看看前后指针是否指向同一个位置,然后再试试用指针方式修改这个字符串。
------解决方案--------------------
呵呵,真不巧,你用什么不好,偏用string来演示,string是一个很特殊的引用....

比如:
string str1= "sdsdsd ";
string str2=str1;
这时,如果你 str2= "232323 ";也不会改变str1的值的。
------解决方案--------------------
STRING =“”的时候就等于新分配了
MS专门对STRING有特殊说明


其实楼主的精神很好。很多程序员只是知道基础类型的性质 但是没几个人去试验过

事实说明 要证明 1+1=2 确实比证明 12443 * (344-3455)^2/234423=??要困难很多