通过ref </int>传递List <int>

时间:2012-06-26 18:25:24

标签: c# ref

  

可能重复:
  passing in object by ref

使用下面的代码,输出将是:

Without:
With:1

代码:

    static void Main(string[] args)
    {
        var listWithoutRef = new List<int>();
        WithoutRef(listWithoutRef);
        Console.WriteLine("Without:" + string.Join(" ", listWithoutRef));

        var listWithRef = new List<int>();
        WithRef(ref listWithRef);
        Console.WriteLine("With:" + string.Join(" ", listWithRef));
    }

    static void WithoutRef(List<int> inList)
    {
        inList = new List<int>(new int[] { 1 });
    }

    static void WithRef(ref List<int> inList)
    {
        inList = new List<int>(new int[] { 1 });
    }

通过观察这个,我会说List上有一个List,所以无论如何都是由ref传递的,所以它们应该是一样的吗?我误解了ref关键字吗?或者我错过了其他什么?

2 个答案:

答案 0 :(得分:7)

  

我误解了ref关键字吗?或者我错过了其他什么?

是。您没有将列表本身传递给方法,而是通过引用将引用传递给列表。这样,您就可以更改方法中的引用(List<int>实际引用的listWithRef),并使其反映出来。

不使用ref关键字,您的方法无法更改对列表的引用 - 实际列表存储机制在任何一种情况下都保持不变。

请注意,如果您只想使用列表,则不需要这样做。例如,您可以在任一方法中调用List<int>.Add,该列表将添加新项目。 Ref仅在引用类型中需要更改引用本身。

答案 1 :(得分:3)

是的,所有List对象都以任意方式存储在堆上。但是,如果没有ref关键字,则无法重新分配inList参数,并使其影响调用者的范围。当您创建新的List对象时,它会作为新对象进入堆,但除非您使用引用不会受到影响> ref 关键字。

WithoutRef中,如果您在现有List上调用方法而不重新定义它,您会看到它已被修改:

inList.Clear();
inList.Add(1);