ref的使用

ref 关键字在 C# 中经常使用,但是一直也没有认真考虑过它的确切含义。经常写代码,然而最基本的都还没有搞清楚,真是惭愧呀 :( 以前觉得使用 ref 是传的引用,如果在此方法里面更改参数的值,那此参数对应的变量的值也会被更改。

注:没有REF的方法调用的只是参数的一个副本,有ref传入的时候,是调用的一个引用。

下面的代码是 MSDN 上的例子:

 1 // cs_ref.cs
 2 using System;
 3 public class MyClass 
 4 {
 5   public static void TestRef(ref char i) 
 6   {
 7     // The value of i will be changed in the calling method
 8     i = 'b';
 9   }
10 
11   public static void TestNoRef(char i) 
12   {
13     // The value of i will be unchanged in the calling method
14     i = 'c';
15   }
16 
17   // This method passes a variable as a ref parameter; the value of the 
18   // variable is changed after control passes back to this method.
19   // The same variable is passed as a value parameter; the value of the
20   // variable is unchanged after control is passed back to this method.
21   public static void Main() 
22   {
23   
24     char i = 'a';    // variable must be initialized
25     TestRef(ref i);  // the arg must be passed as ref
26     Console.WriteLine(i);
27     TestNoRef(i);
28     Console.WriteLine(i);
29   }
30 }

输出结果是:

b
b

在上面的例子中,是使用值类型作为参数的。那如果使用对象作为参数,会是什么样的呢?请看下面的代码:

 1 // cs_object_ref.cs
 2 using System;
 3 
 4 public class MyObject
 5 {
 6   public int Data;
 7 }
 8 
 9 public class MyClass 
10 {
11   public static void TestRef(ref MyObject m) 
12   {
13     // The value of MyObject.Data will be changed in the calling method
14     m.Data = 10;
15   }
16 
17   public static void TestNoRef(MyObject m) 
18   {
19     // The value of MyObject.Data will be unchanged in the calling method
20     m.Data = 20;
21   }
22   
23   public static void TestCreateRef(ref MyObject m) 
24   {
25     m = new MyObject();
26     m.Data = 100;
27   }
28   
29   public static void TestCreateNoRef(MyObject m) 
30   {
31     m = new MyObject();
32     m.Data = 200;
33   }
34 
35   public static void Main() 
36   {
37   
38     MyObject m = new MyObject();
39     m.Data = 1;
40     
41     TestRef(ref m);
42     Console.WriteLine(m.Data);
43     
44     TestNoRef(m);
45     Console.WriteLine(m.Data);
46     
47     TestCreateRef(ref m);
48     Console.WriteLine(m.Data);
49     
50     TestCreateNoRef(m);
51     Console.WriteLine(m.Data);
52   }
53 }

输出结果为:

10
20
100
100

我们可以看到在 TestRef 和 TestNoRef 方法中修改参数的值,相应变量的值都会更改,因为都是传递的引用啊:) 但是在后面 TestCreateRef 和 TestCreateNoRef 两个方法中,它们的结果就不太一样了。

在使用 ref 关键字的方法中重新创建实例的时候,不仅方法中变量的引用被更新(这个当然啦,不然创建实例干嘛呀 :)),而且调用者中变量的引用也被同时更新。将好像是在调用者的范围内使用 new 关键字创建对象一样。

而在不使用 ref 关键字的方法中只是将此方法中的变量的引用更改了,并没有更改调用者变量的引用。也就是说在 TestCreateNoRef 方法中对新创建的变量做任何更改,调用者都不会知道!

原文地址:https://www.cnblogs.com/shineqiujuan/p/1360712.html