C# ref与out 的理解

C#中想要解决函数返回多个值的问题,有几种解决办法:

  1. 返回一个容器
  2. 将多个返回值拼接
  3. 使用outref关键字

下面就通过几个例子来详细讲解一下out与ref

  1. 普通方法参数
       static void Main(string[] args)
        {
            int a = 20;
            int b = 30;
            int sum = Method(a, b);
            Console.WriteLine("{0} {1} {2} ", a, b, sum);
        }
        static int Method(int a, int b)
        {
            a = 200;
            b = 300;
            return a+b;
        }

得到结果如为:20,30,500

我们用如下代码查看变量a与参数a在内存中的位置:

        static unsafe void Main(string[] args)
        {
            int a = 20;
            int b = 30;
            int sum = Method(a, b);
            Console.WriteLine("方法外地址:0x{0:x}", (int)&a);
            Console.ReadKey();
        }
        static unsafe int Method(int a, int b)
        {
            a = 200;
            Console.WriteLine("方法内地址:0x{0:x}", (int)&a);
            return a+b;
        }

得到结果为:
这里写图片描述

结论很明显,传入的a,b参数为值类型参数,变量的栈数据会完整地复制到目标参数中即实参和形参中的数据相同但存放在内存的不同位置

2.out关键字修饰的方法参数
首先,out参数修饰的参数在传入方法之前不需要初始化,但在方法内部必须初始化。out参数可以理解为传入参数时候传入的是参数的引用,方法内部对参数的修改会反应在方法之外,类似于传入指针

有如下代码:

static unsafe void Main(string[] args)
        {
            int a = 20;
            int b = 30;
            int sum = Method(out a, b);
            Console.WriteLine("{0} {1} {2} ", a, b, sum);
            Console.ReadKey();
        }
        static unsafe int Method(out int a, int b)
        {
            a = 200;
            b = 300return a+b;
        }

结果为200,30,500

接下来查看a的地址变化,代码如下:

        static unsafe void Main(string[] args)
        {
            int a = 20;
            int b = 30;
            int sum = Method(out a, b);
            Console.WriteLine("方法外地址:0x{0:x}", (int)&a);
            Console.WriteLine("{0} {1} {2} ", a, b, sum);
            Console.ReadKey();
        }
        static unsafe int Method(out int a, int b)
        {
            a = 200;
            b = 300;
            fixed (int* p = &a)
            {
                Console.WriteLine("方法内地址:0x{0:x}", (int)p);
            }
            return a+b;
        }

得到结果为:
这里写图片描述
综合来看,out修饰符修饰的参数,在传入参数时传入了参数的引用,但是没有传入参数的值

3.ref关键字修饰的方法参数
ref修饰符修饰的参数,传入方法之前必须初始化,具体代码如下:

static unsafe void Main(string[] args)
        {
            int a = 20;
            int b = 30;
            int sum = Method(ref a, b);
            Console.WriteLine("{0} {1} {2} ", a, b, sum);
            Console.ReadKey();
        }
        static unsafe int Method(ref int a, int b)
        {
            a = 200;
            b = 300return a+b;
        }

输出结果为:200,30,500
同样使用如下代码查看内存:

static unsafe void Main(string[] args)
        {
            int a = 20;
            int b = 30;
            int sum = SwapMethod(ref a, b);
            Console.WriteLine("方法外地址:0x{0:x}", (int)&a);
            Console.WriteLine("{0} {1} {2} ", a, b, sum);
            Console.ReadKey();
        }
        static unsafe int SwapMethod(ref int a, int b)
        {
            a = 200;
            b = 300;
            //Console.WriteLine("方法内地址:0x{0:x}", (int)&a);
            fixed (int* p = &a)
            {
                Console.WriteLine("方法内地址:0x{0:x}", (int)p);
            }
            return a+b;
        }

输出结果为:
这里写图片描述

综上所述,可以得到结论,ref修饰的参数,是将变量的引用与值同时传入。

4.out与ref的异同
通过上述实例,可以看出,out与ref关键字都是用来修饰参数,将原本拷贝参数值的操作变成了传入参数引用。只是差别在于ref传入参数值与参数引用,而out只传入参数引用。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值