2010-12-19 50 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