请教各位高手,object是引用类型。可是为什么我下面的代码
object z = 156;
object m = z;
m = 123;
Console.WriteLine("{0},{1}",z,m);
Console.ReadKey();
输出的结果是156,123
请问这是为什么?
object z = 156;
object m = z;
m = 123;
Console.WriteLine("{0},{1}",z,m);
Console.ReadKey();
输出的结果是156,123
请问这是为什么?
int z = 156;
int m = z;
m = 123;
Console.WriteLine("{0},{1}",z,m);
Console.ReadKey();
类型转换相关的装箱、取消装箱
http://www.orsoon.com/article/article_12513.html
把你的代码改为
object z = 156;
object m = (object)z;
m = 123;
Console.WriteLine("{0},{1}",z,m);
Console.ReadKey();
再测试下
关键是这句 object m = z;
你觉得 m 应该是 z 的引用。或者你会这么写:object m = (object)z;
这样做其实是无效的。你可能认为(object)z是把z转换成object,其实不是,因为这是隐式类型转换,其实是“把z当作object”,而不是把z转换为object,因此在它身上发生了一次装箱一次拆箱。
当它传给m的时候,它还是int。
这是一个装箱操作,生成了一个引用类型,m引用的对象和z引用的对象就不同了,
装箱操作的机制:
1、在托管堆中分配好内存。(同步块+方法表+值类型的字段)
2、将值类型的字段复制到托管堆中。
3、返回对象的地址。m = 123;这是一个装箱的操作。
在装箱之前m和z确实都是指向一个托管堆中的。但是由于装箱操作的机制。重新分配了内存,重新返回对象的地址。之前指向156的引用就撤销了。
object m = z;//此时m的值也为156
m = 123;//m的值从156变为123
Console.WriteLine("{0},{1}",z,m);//综上,z知值为156,m值为123
object z = 156; //把156装箱,但z的本质还是156;
object m = z;//把z给m,这里没有拆箱,m和z是一样的。 m==z m.GetHashcode()==z.GetHashcode()
m = 123; //这里又一次装箱,这是关键,相当于给了m一个新的对象,或者通俗的说是新的箱子,但是不会影响z,对m来说,m只是把z扔掉了,换成了123,而不是把z改成了123。
Console.WriteLine("{0},{1}",z,m);
Console.ReadKey();
当然这个问题只是引用类型的特点决定的。
object m1 = new object();
object m2 = m1;
Console.WriteLine(m1.GetHashcode()==m2.GetHashcode()); //true
m2 = new object();
Console.WriteLine(m1.GetHashcode()==m2.GetHashcode()); //false所以才有了out这个关键字,再说就太多了...