在AnyTao<参数之惑>基础之上再讨论按值传递与按引用传递
看了AnyTao的按值传递与按引用传递,我感觉自己以前好像并没有弄明白到底什么是按值传递,什么是按引用传递。以前,误以为:传递的参数为引用类型的就是按引用传递。其实,这是一个误解。
下面先以一个例子分析:
public class COboject
{
public int i = 10;
}
示例一:直接对象的成员的值
public class Form1
{
private void Form1_Load(object sender, EventArgs e)
{
COboject abf = new COboject();
MessageBox.Show(abf.i.ToString());//10
ChangeValue(abf);//50
MessageBox.Show(abf.i.ToString());//50
}
private void ChangeValue(COboject cobj)
{
cobj.i = 50;
MessageBox.Show(cobj.i.ToString());
}
}
用内存图示进行分析:
说明一点,值类型与引用类型内存分配的不同是值类型分配在线程堆栈中,引用类型分配在托管堆中,但是线程堆栈中会分配该引用类型在托管堆中的地址。
所以,调用ChangeValue()函数时在线程堆栈中执行了对abf对象的拷贝。
示例二:改变对象的引用(表面上改变)
为什么后面括号里面写上“表面上改变”呢,原因是调用函数的对象实质上未改变,只是被调用函数内改变了。
public class Form1
{
private void Form1_Load(object sender, EventArgs e)
{
COboject abf = new COboject();
MessageBox.Show(abf.i.ToString());//10
ChangeObject(abf);//50
MessageBox.Show(abf.i.ToString());//10
}
private static void ChangeObject(COboject cobj)
{
COboject tempObj = new COboject();
tempObj.i = 50;
cobj = tempObj;
MessageBox.Show(cobj.i.ToString());
}
}
用内存图示进行分析:
说明:对象在被调用函数内的指针发生变化了,但是这个对象只是调用函数内的拷贝,所以调用函数内的对象地址不变。
示例三:调用函数内对象的真正改变
public class Form1
{
private void Form1_Load(object sender, EventArgs e)
{
COboject abf = new COboject();
MessageBox.Show(abf.i.ToString());//10
ChangeRef(ref abf);//50
MessageBox.Show(abf.i.ToString());//50
}
private static void ChangeRef(ref COboject cobj)
{
COboject tempObj = new COboject();
tempObj.i = 50;
cobj = tempObj;
MessageBox.Show(cobj.i.ToString());
}
使用ref关键字,告诉编译器,我传递的是对象的地址的地址,所以当在被调用函数内部更改对象的地址时,调用函数的对象地址也改变了。具体怎么画这个内存图示,虽然脑袋里面有个概念,可是不知道怎么画了,不好意思,大家能理解意思就好。如果有哪位高手可以不吝赐教,给出改图示,LZ在此大谢特谢!!!