C# 當陣列引數引用傳遞 遇上 new
阿新 • • 發佈:2019-01-02
請看下面程式碼:
static void Main(string[] args) { int[] a = new int[]{ 1, 2, 3 }; Test_1(a); Console.WriteLine(string.Join(",", a)); Test_2(a); Console.WriteLine(string.Join(",", a)); Console.ReadLine(); } private static void Test_1(int[] a) { a = new int[] { 100, 200, 300 }; } private static void Test_2(int[] a) { a[1] = 10; }
請看輸出結果:
是不是覺得很意外?!
為了更好地解釋清楚,我將上面的兩個 Test 方法的引數名改一下:
private static void Test_1(int[] b)
{
b = new int[] { 100, 200, 300 };
}
private static void Test_2(int[] c)
{
c[1] = 10;
}
首先需要說明的是,陣列是引用型別,引數傳遞的時候是引用傳遞(傳遞記憶體地址)的。
當呼叫Test_1方法時,CLR在棧上建立了一個變數b,並將變數a儲存的堆地址賦值給變數b(變數a與變數b是兩個獨立的變數,雖然它們都指向了同一個堆地址,理解這一點很重要)。
Test_1方法內部 new 了一個新的陣列,CLR會開闢一個新的堆空間,並將該堆地址賦值給變數b,此時變數a儲存的堆地址不變,也就是說此時變數a與變數b分別指向了不同的堆地址,所以變數a的值並沒有變。
下面上圖,能更好的理解(畫的不好不要介意哈):
至於Test_2方法,變數c與變數a都是指向同一個堆地址,所以改變了變數c的值也就導致變數a的值變了。
參考連結: