2012-05-21 37 views
-2

有一个用户定义的类,像这样:ArrayList对象的引用

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

+1

为什么你不去运行它首先,看看什么等于a.dummy? –

+0

使用属性访问器而不是公共字段。而且最好使用通用列表结构。 – Bedasso

回答

1

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

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

为什么 - >

Consider var arr = new ArrayList(); 

上面的语句首先创建一个ArrayList对象和引用被分配给编曲。 (对于任何Class,这与类是引用类型相似)。

现在,在主叫时,

example -> DummyMethod(arr) , 

基准通过值传递,也就是即使参数被分配给该方法内的不同对象,原始变量保持不变。
但是,当变量指向(指向)同一个对象时,在底层尖端对象上完成的任何操作都会反映到被调用方法之外。
在你的例子中,每一个修改都会反映在arrayList中。

如果你想避免这种行为,你必须创建对象的复制/克隆。

例子:

而不是

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

使用

foreach (Foo x in (ArrayList)dummyfoo.Clone()) 
     x.dummy++; 
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

你宣布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类型。

1

它已经2:这里是your code on ideone用来验证..

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

P.S.泛型从C#2.0开始可用,所以考虑使用List<Foo>代替ArrayList以提高类型安全性。