前阵子有人问了这样一道问题,就是说,明明类是引用类型,为什么传递进方法之后的改变不会改变到Main方法里面的值。
从这里,我想有必要解释一下。
首先传递一般有四种情况,值类型按值传递,值类型按引用传递,引用类型按值传递,以及引用类型按引用传递。
我们先看下面的代码:










































如上所示,我们可以看到两种传递情况:
分别是:引用类型按值传递,跟值类型按值传递,
首先值类型按值的传递很多人都了解,过程是:
发生方法调用时,CLR 生成了一个相对应的副本,并将该副本传递进方法中,以后的修改都只针对副本,而不会改变原来的值。
然后我们详细讨论一下,引用类型的传递。
同样的,当我们调用下面的方法时;
很多人就会问,引用类型传递的不是他本身吗?其实这里有个误区,引用类型传递的是引用而不是他本身,
就像这样:
{
i = 0;
V.i = 20;
Value val = new Value();
V = val;
Console.WriteLine(v.i + " " + i + " ");
}
在这个方法体中,我们可以用一个v来代替传递进来的Value;其实发生的是这样的一种情况,
方法开始时,CLR为我们创建了一个
Value V = 传递进来的v
画成图应该是这样:
然后方法调用的时候,产生了一个v的copy,就是V,也指向托管堆中v的确切数据。
然后我们看到了方法体中这样的代码:
Value val = new Value();
V = val;
首先因为V现在是指向 v的确切数据的, 所以V.i = 20 改变了外面v.i的值。
很多人就在这里迷惑了,觉得,这时方法外的v也会因为Value的构造函数,而变成15,
但事实是那个我们在内存里发生的却是这样的情况:
因为Value val = new Value();
产生了一个新的对象,并由Val指向它。
接着,又因为以下代码,: V = vla; 使得V 指向了val所在的数据
最后,因为val 只是个局部变量,在方法结束后他就会结束它的生命周期,等待垃圾回收。
暂时讲到这里,太长了…下回待续。>_< 欢迎各位敲砖~