C#中ref、out、in的区别与使⽤
ref 修饰符,指定参数由引⽤传递,可以由调⽤⽅法读取或写⼊。
out 修饰符,指定参数由引⽤传递,必须由调⽤⽅法写⼊。
in 修饰符,指定参数由引⽤传递,可以由调⽤⽅法读取,但不可以写⼊。
遂码之,⾸先是in:
可以看到,不能对in参数赋值,可见只能读,不能写
再来
可以看到,out参数不能读,只能写,就算在main中初始化,也是当做未赋值来看待
最后再来
ref没有任何报错,可见是可读可写的,了解,还有就是ref参数必须初始化,不然会报错,in也是。
ref、out、in参数不能当做重载的依据
ref、out、in都是将参数按引⽤来传递,我们普通做法什么都不加是⽤的值传递,这在内存分配上是有差异的。
ref:可读可写(可进可出)
out:只能写不能读(只出不进)
in:只能读不能写(只进不出)
In:过程不会改写In的内容
out:传⼊的值不会被过程所读取,但过程可以写
ref:传⼊的值,过程会读,也会写
通常我们向⽅法中传递的是值.⽅法获得的是这些值的⼀个拷贝,然后使⽤这些拷贝,当⽅法运⾏完毕后,这些拷贝将被丢弃,⽽原来的值不将受到影响.此外我们还有其他向⽅法传递参数的形式,引⽤(ref)和输出(out).
有时,我们需要改变原来变量中的值,这时,我们可以向⽅法传递变量的引⽤,⽽不是变量的值.引⽤是⼀个变量,他可以访问原来变量的值,修改引⽤将修改原来变量的值.变量的值存储在内存中,可以创建⼀个引⽤,他指向变量在内存中的位置.当引⽤被修改时,修改的是内存中的值,因此变量的值可以将被修改.当我们调⽤⼀个含有引⽤参数的⽅法时,⽅法中的参数将指向被传递给⽅法的相应变量,因此,我们会明⽩,为什么当修改参数变量的修改也将导致原来变量的值.
创建参数按引⽤传递的⽅法,需使⽤关键字ref.例;
using System;
class gump
{
public double square(ref double x)
{
x=x*x;
return x;
}
}
class TestApp
{
public static void Main()
{
gump doit=new gump();
double a=3;
double b=0;
Console.WriteLine(\"Before square->a={0},b={1}\",a,b);
b=doit.square(ref a);
Console.WriteLine(\"After square->a={0},b={1}\",a,b);
}
}
通过测试,我们发现,a的值已经被修改为9了.
通过指定返回类型,可以从⽅法返回⼀个值,有时候(也许还没遇到,但是我们应该有这么个⽅法),需要返回多个值,虽然我们可以使⽤ref来完成,但是C#专门提供了⼀个属性类型,关键字为out.介绍完后,我们将说明ref和out的区别.
通过使⽤out关键字,我们改变了三个变量的值,也就是说out是从⽅法中传出值.
using System;
class gump
{
public void math_routines(double x,out double half,out double squared,out double cubed)
//可以是:public void math_routines(ref double x,out double half,out double squared,out double cubed)
//但是,不可以这样:public void math_routines(out double x,out double half,out double squared,
//out double cubed),对本例来说,因为输出的值要靠x赋值,所以x不能再为输出值
{
half=x/2;
squared=x*x;
cubed=x*x*x;
}
}
class TestApp
{
public static void Main()
writeline输出数值变量{
gump doit=new gump();
double x1=600;
double half1=0;
double squared1=0;
double cubed1=0;
[Page]
/*
double x1=600;
double half1;
double squared1;
double cubed1;
*/
Console.WriteLine(\"Before method->x1={0}\",x1);
Console.WriteLine(\"half1={0}\",half1); Console.WriteLine(\"squared1={0}\",squared1);
Console.WriteLine(\"cubed1={0}\",cubed1);
doit.math_rountines(x1,out half1,out squared1,out cubed1);
Console.WriteLine(\"After method->x1={0}\",x1);
Console.WriteLine(\"half1={0}\",half1);
Console.WriteLine(\"squared1={0}\",squared1);
Console.WriteLine(\"cubed1={0}\",cubed1);
}
}
我们发现,ref和out似乎可以实现相同的功能.因为都可以改变传递到⽅法中的变量的值.但是,⼆者本质本
质的区别就是,ref是传⼊值,out是传出值.在含有out关键字的⽅法中,变量必须由⽅法参数中不含out(可以是ref)的变量赋值或者由全局(即⽅法可以使⽤的该⽅法外部变量)变量赋值,out的宗旨是保证每⼀个传出变量都必须被赋值.
上⾯代码中被/**/注释掉的部分,可以直接使⽤.也就是说,在调⽤⽅法前可以不初始化变量.但是"x1"是要赋值的,否则要报错.⽽ref参数,在传递给⽅法时,就已经是还有值的了,所以ref侧重修改.out侧重输出(返回值).
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论