正确认识C#中的引用传递,其实引用传递实际上也是属于值传递
来源:互联网 发布:php汽车门户系统 编辑:程序博客网 时间:2024/04/29 13:42
以前一直误以为引用类型,在作为参数传递时,都是引用传递(类似于值传递中的ref),也就是说,把引用类型的变量作为参数传递给方法,在方法中修改该参数,会改变这个变量的值,
后来通过一些事例发现,上面的认识是片面的,引用类型传递实际上也是属于值传递的,只是引用类型传递的是一个堆地址。
先来个例子吧:
- using System;
- public class test{
- public static void Main(){
- testClass a = new testClass();
- ChangeToNull(a);
- Console.WriteLine(string.Format("a不是null,它的属性值为:{0}", a.field));
- ChangeField(a);
- Console.WriteLine(string.Format("a的属性值为:{0}", a.field));
- ChangeToNull(ref a);
- Console.WriteLine(string.Format("a是不是null:{0}", (a == null)));
- }
- static void ChangeToNull(testClass b){
- b = null;
- if(b == null){
- Console.WriteLine("在ChangeToNull方法中,参数已经被修改成null了!");
- }
- }
- static void ChangeField(testClass b){
- b.field = 0;
- Console.WriteLine("在ChangeField方法中,参数的成员已经被修改成0了!");
- }
- static void ChangeToNull(ref testClass b){
- b = null;
- if(b == null){
- Console.WriteLine("在ChangeToNull使用ref的重载方法中,参数已经被修改成null了!");
- }
- }
- }
- class testClass{
- public int field;
- public testClass(){
- field = 123;
- }
- }
上面的代码,执行后的结果是:
在ChangeToNull方法中,参数已经被修改成null了!
a不是null,它的属性值为:123
在ChangeField方法中,参数的成员已经被修改成0了!
a的属性值为:0
在ChangeToNull使用ref的重载方法中,参数已经被修改成null了!
a是不是null:True
由此可见,引用类型作为参数时:
1、在修改变量本身时,结果类似于值传递,即不会改变传递前的变量的值
2、在修改变量的属性或字段时,才是引用传递,会影响到传递前的变量的值
3、参数使用了ref后,才是真正的引用传递,不管修改变量本身还是修改变量的属性或字段,都会影响到传递前的变量的值
究其原因,我们知道,值类型和引用类型,在运行时,它们存放的位置是不同的,值类型是存储在进程的栈上的
而引用类型是存储在进程堆(Heap)上的,在进程的栈上存储了这个引用类型在堆上的地址
而在调用方法时,是把栈上的参数的值复制一份传递给方法,所以值类型作为参数传递时,不会改变原变量值很明显
引用类型传递时,也是一样,把栈上的这个堆地址复制一份传递给方法,
所以在方法里修改这个复制的地址的值,当然不会改变原变量的值,
但是修改这个复制的地址所指向的堆里的内容,那原变量指向的地址的内容当然也跟着改变了。
如果参数加了ref,那传递的就是栈的地址的,此时不管是值类型还是引用类型,都会改变原变量的内容
综上所述,我们可以知道,引用类型作为参数传递,不能单纯的说它就是引用传递,如果直接这么认为,在开发中难免会犯错误的,深入的理解一下值类型和引用类型的传递,还是很有必要的。
- 正确认识C#中的引用传递,其实引用传递实际上也是属于值传递
- 正确认识C#中的引用传递,其实引用传递实际上也是属于值传递
- c#引用传递,值传递,引用传递实际上也是属于值传递
- C#中的引用传递、值传递。
- C#中的引用传递、值传递
- C#中的引用传递和值传递
- C#中的引用传递、值传递
- C#中的引用传递、值传递。
- C#中的引用传递和值传递
- C#中的引用传递、值传递。
- C#中的引用传递、值传递
- C#中的引用传递、值传递。
- 值传递、引用传递
- 值传递引用传递
- 值传递,引用传递??
- 值传递 引用传递
- 引用传递、值传递
- 值传递引用传递
- LL和我一起病了。
- Mdi分栏方法总结
- 我的学习笔记(国际化,设置Cookie)
- 2009年SOA七大预测:云计算推动SOA
- RTDX在图像处理中的应用
- 正确认识C#中的引用传递,其实引用传递实际上也是属于值传递
- 模板方法的一般实现:
- 软件人才体系图
- 有几个天使
- 你的公司有鸡鸣狗盗之徒吗?
- 你是自暴自弃的人吗?
- 即将卸任的技术总监的困惑
- 系统架构师的修炼
- 软件设计师具备的知识与能力