2010-12-19 55 views
0

任何人都可以解釋如何在調用具有列表集合作爲參數的方法時完成內存分配。由於下面的代碼片段顯然似乎結果相同,但不會產生相同的結果。 所以我想知道兩種方法調用在內存分配方面的差異。列表集合對象作爲方法參數

using System; 
using System.Collections.Generic; 
namespace ListSample 
{ 
    class ListSampleClass 
    { 
     static void Main(string[] args) 
     { 
      List<int> i = new List<int>(); 
      i.Add(10); 
      i.Add(15); 
      SampleMethod1(i); 
      Console.WriteLine("Result of SampleMethod1:"+i[0]); 
      SampleMethod2(i); 
      Console.WriteLine("Result of SampleMethod2:" + i[0]); 
      Console.ReadKey(); 
     } 

     public static void SampleMethod1(List<int> i) 
     { 
      List<int> j = new List<int>(); 
      j.Insert(0,20); 
      i = j; 
     } 

     public static void SampleMethod2(List<int> i) 
     { 
      List<int> j = new List<int>();    
      j = i; 
      j.Insert(0, 20); 
     } 
    } 
} 

回答

6

除非指定refout,參數是按值傳遞。對於參考類型,這意味着參考到對象(​​在這種情況下爲List<int>)是按值傳遞的。

「按值傳遞」是指該參數(在調用語句中的表達式),然後將所得的值被複制到參數(在方法簽名中列出的變量)。在分配給它一個新的值方面,參數的任何進一步變化是調用者看到的而不是。 (但請繼續閱讀...)

這意味着,在你的第一個方法調用:

public static void SampleMethod1(List<int> i) 
{ 
    List<int> j = new List<int>(); 
    j.Insert(0,20); 
    i = j; 
} 

你正在創建一個新的列表,在插入一個值,然後複製引用新列表到i - 但那根本沒有影響。該參數實際上只是另一個局部變量 - 變量本身值的改變不會影響調用者。

現在你的第二個方法比較:

public static void SampleMethod2(List<int> i) 
{ 
    List<int> j = new List<int>();    
    j = i; 
    j.Insert(0, 20); 
} 

這將創建一個新的列表,然後立即忽略它,而不是分配的參考傳遞的列表(如i)到j。然後它將一個值插入到列表中。該方法的最終結果是將值插入到列表中。這相當於:

public static void SampleMethod2(List<int> i) 
{ 
    i.Insert(0, 20); 
} 

注意,這不是改變參數的值。它正在對參數值引用的對象進行更改。這是一個至關重要的區別瞭解。

我有一篇關於parameter passing的文章,另一篇關於reference and value types,這可能會幫助您更好地理解這一點。

+0

感謝您的快速響應,如果是這樣,那麼不應該SampleMethod2()也給我與SampleMethod1()相同的結果? – Ardentaj 2010-12-19 09:19:51

+0

@Ardentaj:No - 調用'SampleMethod1'對傳入的列表沒有* nothing,因爲在方法中創建的列表上調用了'Insert'方法。 'SampleMethod2'會將值插入到傳入的列表中。 – 2010-12-19 09:22:19

+0

感謝Jon ...我會通讀你的文章,並且你會建議任何可用的內存分析器,以便我可以分配內存分配 – Ardentaj 2010-12-19 09:28:36

相關問題