对象引用的ArrayList

时间:2012-05-21 14:52:16

标签: c# pass-by-reference

拥有用户定义的类,如下所示:

class Foo
    {
        public int dummy;

        public Foo(int dummy)
        {
            this.dummy = dummy;
        }
    }

然后有这样的事情:

ArrayList dummyfoo = new ArrayList();

Foo a = new Foo(1);
dummyfoo.add(a);

foreach (Foo x in dummyfoo)
    x.dummy++;

a.dummy多少钱?

如何创建我的ArrayList以使a.dummy等于2,这意味着我的ArrayList基本上包含指向我的对象的指针,而不是副本。

4 个答案:

答案 0 :(得分:2)

它已包含引用,而不是副本。这样做时:

Foo a = new Foo(1);
dummyfoo.Add(a);

传递了对a的引用,而不是副本。

因此,dummy最初为1,然后在增量后为2。

无论如何,你最好使用泛型:

List<Foo> dummyfoo = new List<Foo>();

Foo a = new Foo(1);
dummyfoo.Add(a);

foreach (Foo x in dummyfoo)
    x.dummy++;

答案 1 :(得分:2)

它已经是2,因为默认情况下,Array / Collections(确切地说是任何.NET类/引用类型)都是通过引用传递的。

实际上,引用变量是按值传递的,但其行为就像通过引用传递一样。

为什么 - &gt;

  Consider var arr = new ArrayList();

上述语句首先创建一个ArrayList对象,并将引用分配给arr。 (对于任何类都是类似的,因为类是引用类型)。

现在在打电话时,

example ->    DummyMethod(arr) , 

引用按值传递,即使参数分配给方法中的其他对象,原始变量也保持不变。
但是当变量指向(引用)同一个对象时,对底层指向对象所做的任何操作都会反映在被调用方法之外 在您的示例中,对每个进行的任何修改都将反映在arrayList中。

如果您想避免此行为,则必须创建对象的复制/克隆。

示例:

而不是

foreach (Foo x in dummyfoo)
        x.dummy++;

使用

foreach (Foo x in (ArrayList)dummyfoo.Clone())
        x.dummy++;

答案 2 :(得分:1)

您将Foo声明为一个类。课程是reference types。它已经像这样工作了。试一试:

class Program
{
    static void Main(string[] args)
    {
        ArrayList dummyfoo = new ArrayList();

        Foo a = new Foo(1);
        dummyfoo.Add(a);

        foreach (Foo x in dummyfoo)
            x.dummy++;

        Console.WriteLine(a.dummy); //Prints 2!
    }
}

class Foo
{
    public int dummy;

    public Foo(int dummy)
    {
        this.dummy = dummy;
    }
}

除此之外,通用List<T>优先于已弃用的ArrayList类型。

答案 3 :(得分:1)

已经2your code on ideone验证了这一点。

值类型(即struct s)不同,引用(即class)对象通过引用传递。

P.S。泛型可用于C#2.0,因此请考虑使用List<Foo>代替ArrayList以提高类型安全性。