2017-08-10 86 views
0

下面是示例代碼:C#變量引用混亂

List<List<Pet>> petsList = new List<List<Pet>>(); 

List<Pet> pets = new List<Pet>() 
{ 
    new Pet {Name = "Whiskers"}, 
    new Pet {Name = "Boots"}, 
    new Pet {Name = "Bradley"}, 
}; 
petsList.Add(pets); 

pets = pets.OrderBy(pet => pet.Name).ToList(); 

foreach (Pet pet in petsList[0]) 
{ 
    Console.WriteLine("{0}", pet.Name); 
} 

的完整代碼可以在這裏找到:https://pastebin.com/raw/uB2B7A9g

這段代碼的輸出中是不是我本來期望。

我本來期望: 靴 布拉德利 威威

但實際產量爲: 威威 靴 布拉德利

不是pets只是一個指針?

所以如果我加petspetsList,然後修改pets,那麼petsList[0]應該指向修改變量?

但是情況並非如此,petsList[0]指向未修改的pets變量。

解決這一問題的唯一辦法就是要做到:

List<List<Pet>> petsList = new List<List<Pet>>(); 

List<Pet> pets = new List<Pet>() 
{ 
    new Pet {Name = "Whiskers"}, 
    new Pet {Name = "Boots"}, 
    new Pet {Name = "Bradley"}, 
}; 

pets = pets.OrderBy(pet => pet.Name).ToList(); 

petsList.Add(pets); 

foreach (Pet pet in petsList[0]) 
{ 
    Console.WriteLine("{0}", pet.Name); 
} 
+1

.Add()函數不會將參數添加到變量中。我想如果你嘗試使用petList [0] = pets並且檢查 – khaled4vokalz

+1

如果你的Add方法簽名是'Add(ref T)',它會工作正常。 –

回答

2

不是寵物只是一個指針?

是,pets是引用類型

所以如果我添加寵物到petsList,然後修改寵物,然後 petsList [0]應該指向修改變量?

正確的情況下當你「修改寵物」
但行pets.OrderBy(pet => pet.Name).ToList();不會修改已存在的集合,而是會返回List<Pet>的新實例。

所以在你的樣品petsList[0]仍然會參考原始集合,其中pets訂購後會引用新的集合。

對於修改已存在的集合,您可以使用List.Sort方法,但由於您的集合是類型爲Pet的集合 - 您需要爲此類型創建自定義比較器。沒有自定義比較器項目將按引用排序。

+0

謝謝,這讓我感覺很多:) – dgamma3

2

你的問題是不是與引用Add()後的平等。 如果添加此檢查的參考平等,你會看到問題出在哪裏:

petsList.Add(pets); 
Console.WriteLine(object.ReferenceEquals(petsList[0],pets)); // true 
pets = pets.OrderBy(pet => pet.Name).ToList(); 
Console.WriteLine(object.ReferenceEquals(petsList[0], pets)); // false 

當你寫pets = pets.OrderBy(pet => pet.Name).ToList();要更改引用該pets被捆綁,之後petsList[0]和pets不相等通過參考更多。因此,您還需要將petsList[0]設置爲新的參考。