請看下面代碼:
1 static void Main(string[] args) 2 { 3 int[] a = new int[]{ 1, 2, 3 }; 4 Test_1(a); 5 Console.WriteLine(string.Join(",", a)); 6 Test_2(a); 7 Console.WriteLine(string.Join(",", a)); 8 Console.ReadLine(); 9 } 10 11 private static void Test_1(int[] a) 12 { 13 a = new int[] { 100, 200, 300 }; 14 } 15 16 private static void Test_2(int[] a) 17 { 18 a[1] = 10; 19 }
請看輸出結果:

是不是覺得很意外?!
為了更好地解釋清楚,我將上面的兩個 Test 方法的參數名改一下:
1 private static void Test_1(int[] b) 2 { 3 b = new int[] { 100, 200, 300 }; 4 } 5 6 private static void Test_2(int[] c) 7 { 8 c[1] = 10; 9 }
首先需要說明的是,數組是引用類型,參數傳遞的時候是引用傳遞(傳遞內存地址)的。
當調用Test_1方法時,CLR在棧上創建了一個變量b,並將變量a保存的堆地址賦值給變量b(變量a與變量b是兩個獨立的變量,雖然它們都指向了同一個堆地址,理解這一點很重要)。
Test_1方法內部 new 了一個新的數組,CLR會開辟一個新的堆空間,並將該堆地址賦值給變量b,此時變量a保存的堆地址不變,也就是說此時變量a與變量b分別指向了不同的堆地址,所以變量a的值並沒有變。
下面上圖,能更好的理解(畫的不好不要介意哈):

至於Test_2方法,變量c與變量a都是指向同一個堆地址,所以改變了變量c的值也就導致變量a的值變了。
參考鏈接:
