ref:引用参数
变量作为参数传给方法,同时希望在方法执行完成后,对参数所做的修改能够反映到变量上(个人对这句话的理解为:拿到一个变量在使用后得到另一个变量 并且想保留这个使用后的变量)
首先:在控制台上写一个方法,方法的功能就是交换传入的数值,代码如下
static void TestRef(int x, int y) { int temp; temp = y; y = x; x = temp; }
然后:在 Main 函数里声明两个 int 类型的变量 x,y,然后调用 TestRef 方法。为做直观的对比,这里我把交换 x,y 前和交换 x,y后都在控制台上打印出来,代码如下
static void Main(string[] args) { int x = 10; int y = 20; Console.WriteLine("交换前:x={0},y={1}", x, y); TestRef(x, y); Console.WriteLine("交换后:x={0},y={1}", x, y); Console.ReadKey(); }
启动项目,结果如下
为什么调用TestRef方法之后 x和y的值并没有交换?
原因分析
首先,函数本身没有问题,问题在于 int 是值类型,它所创建的实例不在托管堆中分配内存,而是直接存储在变量中。虽然我们调用了函数 TestRef,但也不过只是复制了一遍 x,y 的值而已。那我们想在调用完交换函数 TestRef 后,x,y的位置可以交换,该怎么做呢?
这就要引入关键字 ref
什么是 ref
ref (全拼:reference):强制要求参数按引用传值。
使用 ref 关键字 有两个注意事项,如下
一:传入参数之前,必须给参数赋值。
二:调用方法时,必须加 ref 关键字。
三:函数可能会改变引用参数的值,所以必须在函数调用中使用“非常量”变量
四:必须使用初始化过的变量。C#不允许假定ref参数在使用他的函数中初始化。
out(输出参数)
使用out关键字后改参数的值将返回给函数调用中使用的变量(在执行函数时使用了一个变量A在执行完函数后得到一个B并且我们用B的值替换掉A的值。)
1.传方法到参数之前,可以不用先赋值。
2.在函数使用out参数时,必须把它看成尚未赋值,在方法内部,必须要有给参数赋值的语句。
结果
即使在调用方法之前,为变量赋值,调用方法之后,还是会更改变量的值,所以没有必要在方法调用之前为实参赋值。
接下来该看一下 ref和out之间的区别了
使用 ref 参数时,传入的参数必须先被初始化。对 out 参数而言,必须在方法中对其完成初始化。
2、使用 ref 和 out 时,在方法的参数和执行方法时,都要加 ref 或 out 关键字,以满足匹配。
3、out 适合用在需要 return 多个返回值的地方,而 ref 则用在需要被调用的方法,修改调用者的引用的时候。
什么时候选择用 ref ? 什么时候选择用 out ?
1、ref 的使用:使用 ref 进行参数的传递时,该参数在创建时,必须设置其初始值,所以ref 侧重于修改;
2、out 的使用:采用 out 参数传递时,该参数在创建时,可以不设置初始值,但是在方法中必须初始化,所以 out 侧重于输出;
当希望方法返回多个值时,可以用 out,并且一个方法中的参数可以有一个或多个 out 参数;
使用 out 参数,必须将参数作为 out 参数显式传递到方法中,但是out 参数的值不会被传递到方法中,且属性不是变量,不能作为 out 参数传递。
简单来说:ref 是有进有出,而 out 是只出不进。