关于ref与out的区别
来源:互联网 发布:南京海关数据分中心 编辑:程序博客网 时间:2024/05/29 16:12
这几天一直在公司接受培训,都是一些基础的知识,同时也乘着这个机会巩固一下自己的基础,基础太重要了。前些时一直看的是多线程方面的知识,接下来我会写一些其他方面的知识,毕竟作为一个实习新人得和自己从事的具体方向靠近,不过感觉前些时的多线程学的还不够,今后有空还会继续,暂时到此吧、、、
昨天培训的时候有一个问题是关于ref和out的区别,悲催的我不知道,只晓得它们可以做引用传递,具体区别都没一个概念额,貌似当年教我们C#初级的尹老师提到过一个数字交换实现可以用这个,不过当时也就仅此仅此,今天来学习下下
首先声明下哈,此文参考了网上部分文章内容,然后结合自己的了解和总结,有不对的尽管拍砖
关于ref
经常听到值类型和引用类型,其实本质就是一个存储值一个存储地址,看看下面一段代码:
1 public class Test 2 { 3 public int num; 4 public Test(int x) 5 { 6 this.num = x; 7 } 8 public void ChangeNum(Test x) 9 {10 x = new Test(100);11 }12 }13 class Program14 {15 static void Main(string[] args)16 {17 Test ts = new Test(10);18 ts.ChangeNum(ts);19 Console.WriteLine(ts.num);20 Console.ReadKey();21 }22 }
对于以上代码,你认为会输出什么结果?10?100?正确结果是10,猜100的肯定有疑问了、、、
接下来我改两个位置,就不复制整个了,贴出改位置的两个位置,如下所示:
ts.ChangeNum(ref ts); //改上面第18行 public void ChangeNum(ref Test x) //改上面第8行
对于这次的结果又得探讨了,10?还是100?正确结果为100
以上截图,左边是原始代码变量ts和x的地址,右边是修改两个位置后的ts和x的地址,从上面我们可以清晰的看见左图ts地址(0x05f0eb2c)和x地址(0x05f0eacc)不同,右图中ts的地址(0x0568ee6c)和x的地址(0x0568ee6c)相同。就是由于原始代码中Main函数中的ts和Test中的x不是同一个变量,所以后面执行18行代码不会对num值产生任何影响,而后面的两行代码就不同,因为所指向的是同一个变量,所以结果自然得以修改变为100
关于out
还是来看一段代码,事实比较好说话,呵呵:
1 public class Test 2 { 3 public int num; 4 public Test(int x) 5 { 6 this.num = x; 7 } 8 public void ChangeNum(out Test x) 9 {10 x = new Test(100);11 }12 }13 class Program14 {15 static void Main(string[] args)16 {17 Test ts = new Test(10);18 Test x;19 ts.ChangeNum(out x);20 Console.WriteLine(ts.num);21 Console.WriteLine(x.num);22 Console.ReadKey();23 }24 }
以上这段代码执行打印的两个结果也是不同的,分别打印10和100,原理和上面差不多一样,是不是感觉和上面讲的ref很有点象,没错,所以有了今天的标题“关于ref与out的区别”,接下来谈谈其区别吧!
关于out和ref的区别
作为都可以作为引用传递,区别在于值传递。ref传递前必须初始化,而out不必初始化,就算初始化,也会被无视之,out 作为输出参数,可以解决函数只有一个返回值的问题
1 static void Main(string[] args) 2 { 3 Program pg = new Program(); 4 int x; 5 pg.Method_1(out x); 6 Console.WriteLine(x); 7 int y = 1; 8 pg.Method_2(ref y); 9 Console.WriteLine(y);10 Console.ReadKey();11 }12 13 public void Method_1(out int x)14 {15 x = 2; //这一句必须要,不然报错16 Console.WriteLine("调用Medthod_1");17 }18 19 public void Method_2(ref int x)20 {21 x++;22 Console.WriteLine("调用Medthod_2");23 }
运行结果:
怀旧一下当年尹老师讲的a=5和b=10,a与b数值交换,就是用的ref
1 public void yy(ref int x,ref int y) 2 { 3 int temp; 4 temp = x; 5 x = y; 6 y = temp; 7 } 8 static void Main(string[] args) 9 {10 Program pg = new Program();11 int a = 5;12 int b = 10;13 Console.WriteLine("a:" + a + ",b:" + b);14 pg.yy(ref a,ref b);15 Console.WriteLine("a:"+a+",b:"+b);16 Console.ReadKey();17 }
然后以上代码改为用out实现:
1 public void yy(int a,int b,out int x,out int y) 2 { 3 x = b; 4 y = a; 5 } 6 static void Main(string[] args) 7 { 8 Program pg = new Program(); 9 int a = 5;10 int b = 10;11 Console.WriteLine("a:" + a + ",b:" + b);12 pg.yy(a,b,out a,out b);13 Console.WriteLine("a:"+a+",b:"+b);14 Console.ReadKey();15 }
自我感觉吧,在很多地方ref和out可以互换,起到相同的作用,区别仅仅在于ref传进去的参数必须在调用前初始化,out不必初始化;ref传进去的参数在函数内部可以直接使用,而out不可以;ref传进去的参数在函数内部可以不被修改,但out必须在离开函数体前进行赋值。个人感觉ref可以更随意的使用,out总有那么点别扭,毕竟必须在内部给其赋值。
实习的第一个双休日
貌似此文扯了些不该扯得,但总的来说都是跟随笔主要内容有些相关啦,接下来由于培训内容的相关,得转移重心了,Linq和EF还得再回去看看,所以后期可能写点哪方面相关知识。晚睡的习惯还木有改过来,这是个问题得治啊,听了一晚上的歌,单曲循环"想把我唱给你听",好晚了,睡觉去也!!!
------如果你觉得此文对你有所帮助,别忘了点击下右下角的推荐咯,谢谢!------
- 关于ref与out的区别
- ref与out的区别
- Ref与Out的区别
- out与ref的区别
- ref与out的区别
- ref与out的区别
- ref与out的区别
- out 与 ref 的区别
- Ref与Out的区别
- ref与out的区别
- ref与out的区别
- ref 与out的区别
- Ref 与 Out 的区别
- C#/.NET中关于ref与out的区别
- 关于ref和out的详细区别
- 关于ref和out的详细区别
- 关于out和ref的区别
- 关于ref和out的区别
- 关于多线程学习总结(一) 基本概念了解
- 关于多线程学习总结(二) 了解线程的属性及方法
- 关于多线程学习总结(三) 线程简单基本操作
- 关于多线程学习总结(四) 锁
- 关于多线程学习总结(五) 线程池
- 关于ref与out的区别
- C#中Hashtable容器的了解与使用
- 浅谈Java不同于C++的数组
- 正则表达式(上篇)
- 实现天气预报功能
- 弱弱的玩下Javascript
- 周末了 找个网页特效练练手
- 关于StringBuilder
- 解决asp.net mvc中*.resx资源文件访问报错