ref和out的区别

关于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 Program
14     {
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 Program
14     {
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必须在离开函数体前进行赋值。

 

原文:http://www.cnblogs.com/vchenpeng/p/3203350.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值