2013-02-13 32 views
-5

此代碼的行爲是什麼?將s ==「更改實例」或s ==「初始實例」?更多地方的C#單實例

SomeClass instance = new SomeClass(); 
instance.setName("initial instance") 

List<SomeClass> list1 = new List<SomeClass>(); 
List<SomeClass> list2 = new List<SomeClass>(); 

list1.add(instance); 
list2.add(instance); 

list2.get(0).setName("changed instance"); 
string s = list1.get(0).getName(); 

編輯:好的,我做了一些代碼更改。我寫得很快。編輯2:爲什麼我問這個,不要嘗試?由於我在這臺電腦上沒有IDE,因爲有些限制。

+8

測試這類問題的最佳方法是詢問編譯器。 – SWeko 2013-02-13 22:04:29

+0

您不能直接從列表中調用setName/getName,它們是實例函數..您必須執行list2.First()。setName(... – 2013-02-13 22:04:30

+2

雖然我們可以告訴你這個行爲,但你爲什麼要問我們?只要運行該程序,你就會知道。如果你有一個問題,你不可能通過運行代碼,然後問問 – 2013-02-13 22:04:56

回答

5

對象通過引用傳遞。你有兩個引用同一個對象的列表。因此,更改一個列表中的對象將影響另一個列表中的對象。如果你要傳遞一個基元而不是一個對象,它將被傳遞值。當按值傳遞時,它本質上是一個副本。因此,更改一個列表中的值不會更改另一個列表中的值。

如果您希望某個類具有類似於「值」的行爲,您可以在該類中創建一個返回其自身副本的方法。也就是說,包含成員和屬性等的新對象設置爲與原始值相同的值。

實施例:

public SomeClass Clone() 
{ 
    SomeClass newSomeClass = new SomeClass(); 
    newSomeClass.setName(this.getName()); 
    return newSomeClass; 
} 

然後代碼變爲:

SomeClass instance = new SomeClass(); 
instance.setName("initial instance") 

List<SomeClass> list1 = new List<SomeClass>(); 
List<SomeClass> list2 = new List<SomeClass>(); 

list1.add(instance); 
list2.add(instance.Clone()); 

list2.get(0).setName("changed instance"); 
string s = list.get(0).getName(); 

而結果將是list1的和list2中含有兩種不同的SomeClass的情況下,與不同的名稱。

有關值與引用類型的更多信息,請參閱MSDN

+0

這不完全準確,因爲值類型和引用類型都是從'System.Object'繼承的。 – 2013-02-13 22:12:58

+0

確實如此,但MSDN明確指出基元是除字符串類型之外的值類型。類是引用類型。 [MSDN](http://msdn.microsoft.com/en-us/library/4d43ts61%28v=vs.90%29.aspx) – sparky68967 2013-02-13 22:25:18

+0

很高興看到我的問題的答案,而不是一堆迂腐的評論告訴編譯器不要拿我的僞碼。 – John 2013-02-13 22:26:31

2

「已更改實例」,因爲您只創建了一個實例,因此它們共享該實現。

+1

setName是一個列表項 – 2013-02-13 22:04:36

+0

的方法我真的很高興你的慷慨解答,但請更像僞代碼。我希望你有儘可能多的抽象思維去理解。 – John 2013-02-13 22:24:33

+0

@lazyberezovsky:我意識到,但是如果他使用默認的'List '類型,我不是100%確定的,因爲他的原始形式。我希望修訂能夠澄清。當我去修改和回答時發佈了一個完整的答案。 – Guvante 2013-02-13 22:30:58

3

當您將一個對象添加到兩個列表中,並且您在一個列表中更改該對象時,另一個列表仍將引用同一個對象,並因此具有更新的值。

+0

假設'SomeClass'是一個引用類型,這對我來說聽起來像一個安全的假設。 – 2013-02-13 22:06:29