C#: The connection and difference between ref and out

One: The ref keyword causes parameters to be passed by reference.
The effect is that any changes made to parameters in the method will be reflected in that variable when control is passed back to the calling method. To use a ref parameter, both the method definition and the calling method must explicitly use the ref keyword.
That is to say, the setting and changing of parameters in the method will directly affect the place where the function is called (codes ① and ②). The keyword ref cannot be ignored either in the definition of the function or in the call.
You can compare the code:
Code ①:
复制代码
 1 class Program
 2     {
 3         static void Main(string[] args)
 4         {
 5             Program pg = new Program();
 6             int x = 10;
 7             int y = 20;
 8             pg.GetValue(ref x, ref  y);
 9             Console.WriteLine("x={0},y={1}", x, y);
10 
11             Console.ReadLine();
12           
13         }
14 
15         public void GetValue(ref int x, ref int y)
16         {
17             x = 521;
18             y = 520;
19         }
20     }
复制代码

 

The result of running is 

Code ② :

复制代码
 1 class Program
 2     {
 3         static void Main(string[] args)
 4         {
 5             Program pg = new Program();
 6             int x = 10;
 7             int y = 20;
 8             pg.GetValue(ref x, ref  y);
 9             Console.WriteLine("x={0},y={1}", x, y);
10 
11             Console.ReadLine();
12           
13         }
14 
15         public void GetValue(ref int x, ref int y)
16         {
17             x = 1000;
18             y = 1;
19         }
20     }
复制代码

 

由代码① 和②的运行结果可以看出,在方法中对参数所做的任何更改都将反映在该变量中,而在main函数中对参数的赋值却没有起到作用,这是不是说明不需要进行初始化呢?来看第二点

二:ref定义的参数在使用前必须初始化,无论在函数定义时候参数有没有赋予初值。这条正好区分out指定的参数可以不在调用函数的时候进行初始化。
来看代码③ 以及其运行结果:
复制代码
 1  class Program
 2     {
 3         static void Main(string[] args)
 4         {
 5             Program pg = new Program();
 6             int x;
 7             int y;        //此处x,y没有进行初始化,则编译不通过。
 8             pg.GetValue(ref x, ref  y);
 9             Console.WriteLine("x={0},y={1}", x, y);
10 
11             Console.ReadLine();
12           
13         }
14 
15         public void GetValue(ref int x, ref int y)
16         {
17             x = 1000;
18             y = 1;
19         }    
20     }
复制代码

 

出现的错误为:使用了未赋值的局部变量“x”,“y”。故可以说明ref指定的参数无论在函数定义的时候有没有赋予初值,在使用的时候必须初始化。

三 :对out来说,第一条同样适用。将代码①以及②中的ref全部修改成out,则可与使用ref得到同样的结果。
 
四:out指定的参数必须在函数定义的时候就赋初值。否则则出现错误。对比ref指定的参数则可以不在函数内部进行赋初值,在函数调用时候再赋初值也可以。
代码④:
复制代码
 1 class Program
 2     {
 3         static void Main(string[] args)
 4         {
 5             Program pg = new Program();
 6             int x=10;
 7             int y=233;
 8             pg.Swap(out x, out y);
 9             Console.WriteLine("x={0},y={1}", x, y);
10 
11             Console.ReadLine();
12           
13         }
14 
15         public void Swap(out int a,out  int b)
16         {
17             
18             int temp = a;   //a,b在函数内部没有赋初值,则出现错误。
19             a = b;
20             b = temp;
21         }     
22     
23     }
复制代码

 

出现错误:使用了未赋值的out参数“a”,"b"
则在swap函数定义时候给a,b赋上初值则运行正确。
 
总结以上四条得到ref和out使用时的区别是:
①:ref指定的参数在函数调用时候必须初始化,不能为空的引用。而out指定的参数在函数调用时候可以不初始化;
②:out指定的参数在进入函数时会清空自己,必须在函数内部赋初值。而ref指定的参数不需要。

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326993327&siteId=291194637