大家好,今天是第 8 天 … 來提複製 List 時,物件的複製要如何處理,避免複製完要修改資料時,花了很久時間除錯,才發現資料修改的結果與預期不同...。
其它的集合 (如 Queue) 也要留意這個狀況。
若 List<Type>
的元素是數值型態的話,直接作為參數傳入新 List 的建構式即可:
List<int> intList = new List<int>(oldList);
若元素是參考型別,如物件,使用上面的程式碼進行複製,只會複製參考位址,因此在修改複製的物件時,會連原先的物件也一起修改,稱之為 Shallow Copy。如果需要複製成獨立的物件,則需要逐一元素進行複製。
public class Passenger // 建立一個乘客類別
{
public int id;
public string name;
public string route;
public Passenger(int id, string name, string route)
{
this.id = id;
this.name = name;
this.route = route;
}
public void Show()
{
Console.WriteLine($"{name} ({id}) 正在搭乘路線 {route}");
}
public void SetNewRoute(string route)
{
this.route = route;
}
}
public static void Main()
{
// 建立資料
List<Passenger> listPassenger = new List<Passenger>();
Passenger a = new Passenger(1, "Ming", "301");
Passenger b = new Passenger(2, "Mei", "205");
listPassenger.Add(a);
listPassenger.Add(b);
a.Show();
b.Show();
// 複製 List 和修改物件
List<Passenger> copiedListPassenger = new List<Passenger>(listPassenger);
Passenger c = copiedListPassenger[0]; // 取出複製後的第一個物件
c.SetNewRoute("F01");
// 顯示
c.Show();
a.Show(); // 照理說應該要是原本的 301 才對,但實際會跟著修正為 F01
}
想要讓兩個 List 的物件各自獨立的話,應該要加入以下的程式碼,才會實際的複製物件裡面的值,即 Deep Copy。
// 建立資料
// ...
// Deep Copy List 和修改物件
List<Passenger> copiedListPassenger = new List<Passenger>();
foreach(var p in listPassenger){
Passenger newPassenger = new Passenger(p.id, p.name, p.route);
copiedListPassenger.Add(newPassenger);
}
// 顯示
// ...
(除了用建構式重新建構以外,還有其它 Deep Copy 的方式 … 有興趣者可搜尋 C# Deep Copy 關鍵字。 )
參考資料: