標籤:
基本概念
把資料傳入方法中,可以使方法有多個傳回值。
參數的傳遞
值參數,通過將實參的值複製到形參的方式傳遞資料。值參數的實參可以是變數或者是運算式
下面是一個簡單的值參數傳遞的過程
1 class Program 2 { 3 static void Main(string[] args) 4 { 5 SomeData v1 = new SomeData(); 6 int v2 = 30; 7 Console.WriteLine("v1.value:{0},v2:{1}", v1.value, v2); 8 Calculate(v1, v2); 9 Console.WriteLine("v1.value:{0},v2:{1}", v1.value, v2);10 11 }12 13 static void Calculate(SomeData p1, int p2)14 {15 Console.WriteLine("p1.value:{0},p2:{1}", p1.value, p2);16 p1.value += 50;17 p2 += 50;18 Console.WriteLine("p1.value:{0},p2:{1}", p1.value, p2);19 }20 }21 22 class SomeData23 {24 public int value = 100;25 }
1、在調用void Calculate(SomeData p1, int p2)方法之前,系統為v1和v2分配記憶體,v1的引用和v2儲存在棧中,v1的資料存放區在堆中(PS:手繪的圖字寫的醜,圖也畫的醜,這輩子與美術無緣)
2、開始調用方法時,v1是參考型別所以只複製了v1的引用給了p1,v1和p1同時指向堆中的同一個對象;v2是實值型別,所以直接把值複製給p2
3、在方法執行的過程中,p1的value欄位和p2都加上了50
4、方法執行完成後形參從棧中彈出(展開),最終v2的值沒有改變,v1的值改變了。這也是實值型別和參考型別中常會看到的區別。
引用參數,修飾符ref,實參必須是變數,而且必須在調用前賦值。引用參數並不會給形參在記憶體中開闢新的空間,它只是作為實參的一個別名,在記憶體中和實參指向的是同一個地址。
1 class Program 2 { 3 static void Main(string[] args) 4 { 5 SomeData v1 = new SomeData(); 6 int v2 = 30; 7 Console.WriteLine("v1.value:{0},v2:{1}", v1.value, v2); 8 Calculate(ref v1, ref v2); 9 Console.WriteLine("v1.value:{0},v2:{1}", v1.value, v2);10 11 }12 13 static void Calculate(ref SomeData p1, ref int p2)14 {15 Console.WriteLine("p1.value:{0},p2:{1}", p1.value, p2);16 p1.value += 50;17 p2 += 50;18 Console.WriteLine("p1.value:{0},p2:{1}", p1.value, p2);19 }20 }21 22 class SomeData23 {24 public int value = 100;25 }
輸出參數,修飾符out,實參也必須是變數,和引用參數有些類似,輸出參數的形參也是作為實參的別名,不同的是輸出參數可以不用對實參進行初始化,但是在函數調用的過程中必須對輸出參數賦值,在沒有賦值之前去使用形參的話是不允許的,無法通過編譯。
1 static void Main(string[] args) 2 { 3 SomeData v1; 4 int v2; 5 Calculate(out v1, out v2); 6 Console.WriteLine("v1.value:{0},v2:{1}", v1.value, v2); 7 8 } 9 10 static void Calculate(out SomeData p1, out int p2)11 {12 p1 = new SomeData();13 p1.value = 50;14 p2 = 50;15 Console.WriteLine("p1.value:{0},p2:{1}", p1.value, p2);16 }17 }18 19 class SomeData20 {21 public int value = 100;22 }
參考型別作為值參數,如果將一個新的對象賦值給形參,將會切斷形參和實參之間的關聯
1 static void Main(string[] args) 2 { 3 SomeData v1 = new SomeData(); 4 Console.WriteLine("v1.value:{0}", v1.value); 5 Calculate(v1); 6 Console.WriteLine("v1.value:{0}", v1.value); 7 } 8 9 static void Calculate(SomeData p1)10 {11 p1.value = 60;12 Console.WriteLine("p1.value:{0}", p1.value);13 p1 = new SomeData();14 p1.value = 50;15 16 Console.WriteLine("p1.value:{0}", p1.value);17 }18 }19 20 class SomeData21 {22 public int value = 100;23 }
如果將參考型別作為引用參數(用ref修飾符),在上面的例子中的話v1就是指向值為50的資料,並不會消除形參和實參之間的關聯。這裡我就不再畫圖了
C#基礎整理參數