2012-05-21 51 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以提高類型安全性。