任何人都可以解释在调用具有列表集合作为参数的方法时如何完成内存分配。由于下面的代码片段显然看起来似乎相同,但它不会产生相同的结果。 所以我想知道方法调用在内存分配方面的区别。
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);
}
}
}
答案 0 :(得分:6)
除非您指定ref
或out
,否则参数将按值传递。对于引用类型,这意味着对象的引用(在这种情况下为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上有另一篇文章可能会帮助您更多地了解这一点。