在C#中,ref的意思是按引用傳遞。可以參考C++:
1 int a = 10, b = 20;
2 void swap(int x, int y)
3 {
4 int temp = x;
5 x = y;
6 y = temp;
7 }
如果簡單的調用這個swap,比如:swap(a, b),那麼你根本沒辦法交換這兩個變數的值,因為x和y都是形參,在swap返回的時候,x和y都被釋放了。但如果是這樣定義swap:
1 void swap (int& x, int& y)
2 {
3 int temp = x;
4 x = y;
5 y = temp;
6 }
也就相當於x與a,y與b指向同一個記憶體位址,那麼對x的操作也就相當於對a的操作。那麼在C#裡面,這種效果對於實值型別是很明顯的。
1 class Program
2 {
3 static void Test(ref int b)
4 {
5 b = 2;
6 }
7
8 static void Main(string[] args)
9 {
10 int b = 1;
11 Test(ref b);
12 Console.WriteLine(b);
13 }
14 }
此時的輸出是2,也就是Test方法中的b與Main中的b指向同一個記憶體位址,那麼對Test.b的操作也就是對Main.b的操作。你如果把程式改成:
1 class Program
2 {
3 static void Test(int b)
4 {
5 b = 2;
6 }
7
8 static void Main(string[] args)
9 {
10 int b = 1;
11 Test(b);
12 Console.WriteLine(b);
13 }
14 }
那麼輸出的還是1,因為Test.b不是Main.b的引用,也就是一個單獨的形參。現在再看對於參考型別,會是什麼效果:
1 class TestClass
2 {
3 public int b;
4 }
5
6 class Program
7 {
8 static void Test(TestClass b)
9 {
10 b.b = 2;
11 }
12
13 static void Main(string[] args)
14 {
15 TestClass b = new TestClass();
16 b.b = 1;
17 Test(b);
18 Console.WriteLine(b.b);
19 }
20 }
上面的代碼,輸出的是2,因為b是參考型別,在只需修改b的成員的時候,加不加ref關鍵字都一樣。參考型別本身並不包含資料,僅僅維持了對資料的引用。
因此,使用ref參數,對實值型別對象的作用顯而易見,而對於參考型別,如需修改參考型別內部的資料,則無需使用ref關鍵字;否則,當被調用函數內部需要更改引用本身時,比如在函數內部重新置放對象的引用,則需要使用ref關鍵字。