把數據傳入方法中,可以使方法有多個返回值。
值參數,通過將實參的值復制到形參的方式傳遞數據。值參數的實參可以是變量或者是表達式
下面是一個簡單的值參數傳遞的過程
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 SomeData
23 {
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 SomeData
23 {
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 SomeData
20 {
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 SomeData
21 {
22 public int value = 100;
23 }
如果將引用類型作為引用參數(用ref修飾符),在上面的例子中的話v1就是指向值為50的數據,並不會消除形參和實參之間的關聯。這裡我就不再畫圖了