-2

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

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

4 回答 4

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++;
于 2012-05-21T14:53:52.460 回答
2

它已经是 2,因为数组/集合(准确地说是任何 .NET 类/引用类型)默认通过引用传递。

事实上,引用变量是按值传递的,但表现得就像按引用传递一样。

为什么->

  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++;
于 2012-05-21T15:11:01.807 回答
1

你声明Foo为一个类。类是引用类型。它已经像这样工作了。试试看:

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类型。

于 2012-05-21T14:56:44.427 回答
1

它已经是2:这是您在 ideone上的代码,可以验证这一点。

值类型(即structs)不同,引用(即class)对象是通过引用传递的。

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

于 2012-05-21T14:57:19.073 回答