ref 和out 关键字
通过对CLR的学习,我们可以知道,CLR默认所有方法参数都是传值的。对于引用类型的对象,传递的是对象的引用(指向对象的指针),被调用者拥有该对象的引用的拷贝,能够修改对象,改变对象的值;而对于值类型的实例来说,传递给的是实例的一个副本,被调用者对该副本所做的修改不会影响调用者中的实例。
上面使用的是按传值方式来传递参数。接下来,讲按传引用的方式来传递参数。
C# 中提供了 ref 和 out 关键字以便参数按引用(地址)传递,对值类型使用ref和out,为被调用者分配一个托管指针,该指针指向调用者的变量;对于引用类型的话,为被调用者分配一个托管指针,该指针指向调用者中的对象。
补充一下代码,希望能够更加清晰点:
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 7 namespace MyExamples.App 8 { 9 class Book { 10 11 public String Name; 12 13 /// <summary> 14 /// 按传值方式传递 15 /// </summary> 16 /// <param name="book"></param> 17 /// <param name="count"></param> 18 public void GetInfo(Book book, int count) 19 { 20 book.Name = "Eric"; 21 count = 15; 22 } 23 24 /// <summary> 25 /// 使用ref关键字按传引用传递 26 /// </summary> 27 /// <param name="book"></param> 28 /// <param name="count"></param> 29 public void GetResultInfo(ref Book book, ref int count) { 30 book = new Book() 31 { 32 Name = "jerry" 33 }; 34 count = 10; 35 } 36 37 /// <summary> 38 /// 输出结果 39 /// </summary> 40 /// <param name="book"></param> 41 /// <param name="count"></param> 42 public void GetResult(Book book, int count) 43 { 44 Console.WriteLine("book's Name is {0},Count is {1}", book.Name, count); 45 } 46 47 } 48 49 class Program 50 { 51 static void Main(string[] args) 52 { 53 Book book = new Book() 54 { 55 Name = "jonish" 56 }; 57 58 int Count = 5; 59 60 book.GetInfo(book, Count); 61 book.GetResult(book, Count); 62 63 book.GetResultInfo(ref book, ref Count); 64 book.GetResult(book, Count); 65 } 66 } 67 }
运行结果:
------------------------------------------------------------------------------------------------------------------------------------------------------
ref 和 out相同点:
1.使参数按引用传递,注意这里的“引用”与我们通常说的“对象引用”不一样,可以形象的理解为,类似于C/C++中传指针(地址)。
2.效果是,被调用方对该参数的修改会反映到该变量中,即当调用结束返回时,调用方看到的是修改过的值。
3.方法定义和调用方法都必须显式使用 ref 或者 out 关键字
ref 和 out不同点:
1。传递到 ref 的参数必须最先初始化,即由调用方显式初始化。
2。传递到 out 的参数在传递之前不需要显式初始化,但需要调用方在方法返回之前必须对其赋值。
方法重载时需要注意的地方:
1。ref 和 out 关键字在运行时的处理方式不同,但在编译时的处理方式相同。因此,如果一个方法采用 ref 参数,而另一个方法采用 out 参数,则无法重载这两个方法。
2。但是,如果一个方法采用 ref 或 out 参数,而另一个方法不采用这两类参数,则可以进行重载。
相关MSDN学习资料:
http://msdn.microsoft.com/zh-cn/library/14akc2c7(v=vs.80).aspx
http://msdn.microsoft.com/zh-cn/library/t3c3bfhx(v=vs.80).aspx