List Collection对象作为Method Parameter

0 c# collections methods list invoke

任何人都可以解释在调用具有列表集合作为参数的方法时如何完成内存分配.由于下面的代码片段显然看起来似乎相同,但它不会产生相同的结果.所以我想知道方法调用在内存分配方面的区别.

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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Jon*_*eet 6

除非您指定refout,参数按值传递.对于引用类型,这意味着对值的引用(List<int>在本例中)是通过值传递的.

"按值传递"表示计算参数(调用语句中的表达式),然后将结果值复制到参数(方法签名中列出的变量)中.对于参数的任何进一步更改,在为其分配新值方面,调用者不会看到.(但继续阅读......)

这意味着在您的第一个方法调用中:

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

你正在创建一个新列表,在其中插入一个值,然后将对该新列表的引用复制到i- 但这根本没有任何影响.该参数实际上只是另一个局部变量 - 变量本身的值的变化不会影响调用者.

现在将其与第二种方法进行比较:

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

这将创建一个新列表,然后立即忽略它,而是将引用分配给传入(as i)的列表j.然后它将值插入列表中.此方法的最终结果是将值插入列表中.它相当于:

public static void SampleMethod2(List<int> i)
{
    i.Insert(0, 20);
}
Run Code Online (Sandbox Code Playgroud)

请注意,这不会更改参数的值.它正在对参数值引用的对象进行更改.这是理解的关键区别.

我有一篇关于参数传递的文章和另一篇关于参考和值类型的文章,它可以帮助你更多地理解它.