1. 程式人生 > >C# List引用類型的克隆

C# List引用類型的克隆

add code 引用類型 nor oid pan 測試 bubuko lis

有時候我們想克隆一個List去做別的事,而不影響原來的List,我們直接在list後面加上小點點,發現並沒有Clone這樣的擴展函數。這時候就只有自己擴展了。

嘗試了三種方式,測試都通過了,至於性能方面我還沒有做測試。

一、反射

 1  public static List<T> Clone<T>(this List<T> list) where T : new()
 2         {
 3             List<T> items = new List<T>();
 4             foreach (var
m in list) 5 { 6 var model = new T(); 7 var ps = model.GetType().GetProperties(); 8 var properties = m.GetType().GetProperties(); 9 foreach (var p in properties) 10 { 11 foreach (var pm in
ps) 12 { 13 if (pm.Name == p.Name) 14 { 15 pm.SetValue(model, p.GetValue(m)); 16 } 17 } 18 } 19 items.Add(model); 20 }
21 return items; 22 }

二、序列化(依賴Newtonsoft.Json)

1  public static List<T> Clone<T>(this List<T> list) where T : new()
2         {
3             var str = JsonConvert.SerializeObject(list);
4             return JsonConvert.DeserializeObject<List<T>>(str);
5         }

三、序列化(BinaryFormatter)

 1 public static List<T> Clone<T>(this List<T> list)
 2         {
 3             using (Stream objectStream = new MemoryStream())
 4             {
 5                 IFormatter formatter = new BinaryFormatter();
 6                 formatter.Serialize(objectStream, list);
 7                 objectStream.Seek(0, SeekOrigin.Begin);
 8                 return (List<T>)formatter.Deserialize(objectStream);
 9             }
10         }

測試

1 private void Test()
2 {
3     List<NormalSetting> list = new List<NormalSetting>();
4     list.Add(new NormalSetting { RedisIp = "123" });
5     List<NormalSetting> items = list.Clone();
6     list[0].RedisIp = "456";
7     logMessager.Show("{0}:{1}", list[0].RedisIp, items[0].RedisIp);
8 }

技術分享圖片

註意事項:

第一種方式無需任何依賴。

第二種方式需要Newtonsoft.Json,如果項目中沒有用到它,不推薦使用這種方式。

第三種方式序要給引用類型實體加上[Serializable]特性

C# List引用類型的克隆