2015-03-02 127 views
0

我正在製作一個Bar對象的ArrayList。然後我希望能夠修改包含在ArrayList中的BarType成員。我創建了一個我的代碼的縮短版本,實際上正在做我想做的事情,但我不明白爲什麼它會這樣做。修改ArrayList中的對象成員

在代碼中,我創建了兩個Bar對象,並將它們填充到一個ArrayList中。我將最後一個條目對象從列表中拖出來,將其轉換爲條。但TMP是BAR對象的新實例,但是當我更改TMP中的值時,它會更改我的數組列表中的值。我不知道它爲什麼這麼做,或者這是更改ArrayList中BarType值的最佳方法。

下面是代碼:

ArrayList barArray = new ArrayList(); 

Bar myBar = new Bar(10,20); 

barArray.Add(myBar); // I want to create and keep adding Bar object to my arraylist 

myBar = new Bar(30, 40); 

barArray.Add(myBar); 

Bar tmp = new Bar(5,6); 
tmp = (Bar)barArray[myBar]; // extracting the last Bar Object 
tmp.BarType = true; 
tmp.High = 100;    // too my surprise this change the value in the ArrayList 

所以,下面是我的酒吧類:

public class Bar 
{ 
    public double High, Low; 
    public bool BarType;  // I want to be able to modify this variable 

    public Bar(double Low, double High) 
    { 
     this.Low = Low; this.High = High; 
    } 
} 
+5

任何你需要使用'ArrayList'而不是'List '來折磨的理由? – 2015-03-02 22:33:27

回答

2

但TMP是BAR對象的新實例,但是當我改變的價值TMP它改變我的arraylist中的值

這是不正確的。如果您在C++中使用struct Bar或值類型/拷貝構造函數,但在C#/ .NET中使用所有對象都是堆分配的,並通過引用引用它們,這些引用依次通過值傳遞(這是就是說,引用是通過值傳遞的)。

爲了得到你期待的副本上的分配行爲,改變class Barstruct Bar(或實現IClonable和使用.Clone()以獲得新的Bar實例)。

在這裏,我們在堆上創建的Bar一個新的實例,由名爲tmp

Bar tmp = new Bar(5,6); 

但在這裏,你覆蓋了新的參考到最後一個項目中tmp參考參考訪問在barArray原始tmpBar實例沒有指向它的引用並且將被垃圾收集。

tmp = (Bar)barArray[c]; 

tmp現在處於BarArray基準(實質上是一個別名)到一個項目:

tmp.BarType = true; 
tmp.High = 100; 

...這相當於:

barArray[c].BarType = true; 
barArray[c].High = 100; 

此外,普羅蒂普:只類型(class,struct等)應該有TitleCase名稱以及公共成員(方法,屬性等)。局部變量和參數應該在camelCase。根據您的判斷,字段也應該是camelCase_underscorePrefixed

+1

對象根本不被傳遞 - 引用通過默認值傳遞。說「類對象通過引用傳遞」是誤導性的。 (特別是,它表明使用'ref'作爲類型參數的類是毫無意義的,但事實並非如此。)請參見http:// pobox。com /〜skeet/csharp/parameters.html – 2015-03-02 22:33:50

+1

@JonSkeet「引用是按值傳遞」對於初學者來說是一個令人困惑的概念,儘管我們正在討論英語語義。通過「傳遞引用」我的意思是「分配引用」或「賦值僅僅是引用」,但我很難找到一種方式來描述這種不重複使用具有更深意義的詞語,例如「引用」。 – Dai 2015-03-02 22:38:30

+0

使用準確的單詞 - 這是「參數默認通過值傳遞,參考類型變量的值是引用」。我已經向數以百計的初學者解釋了這個概念 - 雖然需要多一點時間(理想情況下與現實世界的類比),但它比讓人們對傳遞參考的東西感到困惑的概念要好得多意味着,根據我的經驗......我不得不清理那些混亂的人。這不是辯論*英語*語義的問題 - 這是一個正確使用廣爲人知的計算機科學術語的問題。 – 2015-03-02 22:40:01