【问题标题】:ArrayList of object references对象引用的 ArrayList
【发布时间】:2012-05-28 02:12:53
【问题描述】:

有一个用户定义的类,像这样:

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 基本上包含指向我的对象的指针而不是副本。

【问题讨论】:

  • 你为什么不先运行它,看看 a.dummy 等于什么?
  • 使用属性访问器代替公共字段。而且最好使用通用列表结构。

标签: c# pass-by-reference


【解决方案1】:

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

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++;

【讨论】:

    【解决方案2】:

    您将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&lt;T&gt; 优于已弃用的 ArrayList 类型。

    【讨论】:

      【解决方案3】:

      已经是2:这是验证这一点的your code on ideone..

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

      附:泛型从 C#2.0 开始可用,因此请考虑使用 List&lt;Foo&gt; 代替 ArrayList 以提高类型安全性。

      【讨论】:

        【解决方案4】:

        它已经是 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++;
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2014-02-16
          • 1970-01-01
          • 2017-04-07
          • 1970-01-01
          • 2021-06-14
          • 1970-01-01
          • 2012-01-05
          相关资源
          最近更新 更多