您的位置:首页 > 其它

ref out 方法参数

2014-05-06 22:02 302 查看

ref和out两个关键字的作用大致相同,但是有一些微妙但是重要的区别。

两者的行为相似到连编译器都认为这两者不能被重载:
publicvoidSampleMethod(outinti){}
publicvoidSampleMethod(refinti){}
以上重载在编译时将被抛出一个错误,编译器认为out和ref是同样的行为,但是事实上在行为上他们有区别。

共同点:两者的值在调用函数中被修改后都会影响到原始值。



区别:ref一定要初始化,out不需要,因为out在调用方法使用之前会把参数值清空不管原本是什么值,所以out不需要初始化



ref是可能被修改,out是强制调用方法一定要修改其值。



但是上面那句话表明了什么?解读一下,便是ref传入的值在函数体中可能被修改,而out传入的值在函数体中是强制的一定要被赋值。

用在哪儿:方法无须有返回值,便可以获取想要的结果[例如:修改参数的值]

需要指出的是:
1、当我们频繁传递大型参数的时候,比如说DataTable、DataSet...的时候,会节省好多内存资源。
2、当我们想得到方法多样化的处理结果的时候,而我们又不愿意复杂化方法所返回的结果,那么我们可以在方法里定义多个ref或者out,以期得到丰富的结果。比如说,我们调用一个方法,要同时得到string、int、double、bool、Array...等几种不同类型的结果,而return返回object又很复杂的时候,ref和
out的处理效果,看上去将会是多么的赏心悦目...

或者换句话说:ref是有进有出,而out是只出不进

ref关键字使用参数按引用传递,而不是值,通过引用传递的效果是在调用方法中对参数的任何修改都会反映在在该变量中。引用参数的值与基础参数变量的值始终是一样的。

1.属性不是变量,因此不能作为ref参数传递

2.尽管ref和out在运行时的处理方式不同,但它们在编译时的处理方式是相同的。因此,如果一个方法采用ref参数,而另一个方法采用out参数,则无法重载这两个方法。

如果尝试这么做,将导致不能编译该代码。

3.如果一个方法采用ref或out参数,而另一个方法不采用这两类参数,则可以进行重载。

publicclassMyApp{
publicstaticvoidUseRef(refinti){
i+=100;
Console.WriteLine("i={0}",i);
}

staticvoidMain(){

inti=10;
Console.WriteLine("before:i={0}",i);
UseRef(refi);
Console.WriteLine("after:i={0}",i);
}
}
/*before:i=10;
i=110;
*after:i=110;
*/

//out关键字会导致参数通过引用来传递,这引ref关键字类似,但你必须在调用方法里对参数进行重新赋值,否则编译不通过
与ref的不同之处:
1.ref要求变量必须在传递之前进行初始化
2.尽管作为out参数传递的变量不需要在传递之前进行初始化,但需要调用方法以便在方法返回之前赋值

publicclassMyApp{
publicstaticvoidUseOut(outinti){
i+=100;
Console.WriteLine("i={0}",i);
}

staticvoidMain(){

inti;//out这里可以不初始化
Console.WriteLine("before:i={0}",i);
UseOut(outi);
Console.WriteLine("after:i={0}",i);
}
}
/*before:i=0;
i=100;
*after:i=100;
*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: