2013-05-17 121 views
1

我有一個Queue<object>,我將對象插入,但如果在將對象放入隊列後修改對象,隊列中的對象也會發生更改。入隊後在隊列中修改的C#隊列對象

例如

object1 = 1; 
queue.Enqueue(object1); 
object1 = 0; 

如果我然後去看看在排隊,object1將等於0,沒有1就像當我把它放在... 建議?

回答

1

在C#中,除非另外指定,否則通常通過引用傳遞對象。您可以在將對象放入隊列之前克隆對象,然後在更改原始副本時,隊列中的內容將不會更改。

一個的許多方法來實現這一目標是做這樣的事情:

object1 = 1; 
queue.Enqueue(new Object(object1)); 
object1 = 0; 

然後在對象的拷貝構造函數,做一名成員明智深副本:

class myClass 
{ 
    public int i; 
    public Object (Object object1) 
    { 
     this.i = object1.i; 
    } 
} 
+0

我需要做什麼才能在我的對象上獲得.Clone()屬性? (自定義對象)包含一個引用? –

+0

實施IClonable是不好的做法。這個問題解釋了原因。 http://stackoverflow.com/questions/3712449/what-is-the-use-of-iclonable-interface-in-net。 –

+0

@that_guy閱讀我修改後的答案。 [Object.MemberwiseClone](http://msdn.microsoft.com/en-us/library/system.object.memberwiseclone.aspx)方法也會返回淺拷貝,您需要深度複製。 –

2

您的隊列是對象的引用隊列,而不是對象的值。克隆對象並修改不在隊列中工作的克隆對象,或者在將對象放入隊列後不要修改對象。

考慮進一步解釋的類比。想象一下,你必須跟蹤100幅油畫。您選擇使用隊列來跟蹤所有的繪畫。你有兩個選擇,以畫保存在您的隊列:

  1. 皮卡每個畫作,並將其移動到隊列
  2. 存儲隊列中的每一畫的位置

好選項1是難因爲畫很重很大。選項2要容易得多,因爲您需要的只是每幅油畫的簡單參考。但是,對於選項2,任何人都可以在不通過隊列的情況下更改繪畫,因爲繪畫實際上並不在隊列中。選項1被稱爲按值傳遞。選項2稱爲通過引用。這就是C#如何將對象存儲在隊列中。

注意:這個比喻是不完美的,但它應該有助於你理解發生了什麼。

下面的代碼應幫助您解決問題:

object1 = 1; 
queue.Enqueue(object1); 
//Clone is a method you'll need to create on the class 
//C# provides a MemberwiseClone method that should be very helpful 
object2 = object1.Clone(); 
object2 = 2 

MemberwiseClone

或者,你可以存儲與值類型(int,焦炭,BOOL,結構等)的信息,如果你是存儲簡單和小的信息。值類型存儲在帶有選項1的隊列中(按值傳遞)

int a = 1; 
var myQueue = new Queue<int>(); 
myQueue.Enqueue(a); 
a = 2; 
//Prints 1 
Console.WriteLine(myQueue.First()); 
//Prints 2 
Console.WriteLine(a); 
2

其他的答案是正確的在技​​術層面上,但我自問的是「爲什麼我要改變排隊的對象?」。通常情況下,您將一些東西放在隊列中,以便它可以進一步處理。如果你隨後改變它,你發送的是什麼行爲?你究竟在做什麼?原始對象或東西就像對象但不完全是什麼?有什麼區別,它們很重要?哪個版本是正確的?

你如何協調你所做的改變與隊列另一端的結果?

如果你不能,那麼你的過程是有缺陷的。如果可以的話,無論如何改變對象可能並不重要(不太可能是這種情況)。

對我來說,好像你可能在隊列上有太多的東西,而你的對象需要分解和/或處理問題。

0

所有非常好的答案,在搜索了一下之後,似乎使用複製構造函數是最簡單的方法來解決此問題,現在一切似乎都正常。看到這篇文章:https://stackoverflow.com/a/78577/1174574

想法?

+1

似乎合理。兩者都是相似的。兩者都有小的折衷。只要你正確地克隆你的物體,並清楚地表明你是製作深層還是淺層複製品,就應該是好的。 –

+0

看到我的「答案」。現在你知道如何,確保你應該。 – LoztInSpace