這篇文章主要給大家介紹了關於C# List引用類型克隆的3種方法,包括反射、序列化(依賴Newtonsoft.Json) 以及序列化(BinaryFormatter)的實現方法,需要的朋友可以參考借鑑,下面來一起看看吧
前言
有時候我們想克隆一個List去做別的事,而不影響原來的List,我們直接在list後面加上小點點,發現並沒有Clone這樣的擴展函數。這時候就只有自己擴展了。
嘗試了三種方式,測試都通過了,至於性能方面我還沒有做測試。
下面話不多說了,來一起看看詳細的介紹吧
一、反射
public static List<T> Clone<T>(this List<T> list) where T : new() { List<T> items = new List<T>(); foreach (var m in list) { var model = new T(); var ps = model.GetType().GetProperties(); var properties = m.GetType().GetProperties(); foreach (var p in properties) { foreach (var pm in ps) { if (pm.Name == p.Name) { pm.SetValue(model, p.GetValue(m)); } } } items.Add(model); } return items; }
二、序列化(依賴Newtonsoft.Json)
public static List<T> Clone<T>(this List<T> list) where T : new() { var str = JsonConvert.SerializeObject(list); return JsonConvert.DeserializeObject<List<T>>(str); }
三、序列化(BinaryFormatter)
public static List<T> Clone<T>(this List<T> list) { using (Stream objectStream = new MemoryStream()) { IFormatter formatter = new BinaryFormatter(); formatter.Serialize(objectStream, list); objectStream.Seek(0, SeekOrigin.Begin); return (List<T>)formatter.Deserialize(objectStream); } }
測試
private void Test() { List<NormalSetting> list = new List<NormalSetting>(); list.Add(new NormalSetting { RedisIp = "123" }); List<NormalSetting> items = list.Clone(); list[0].RedisIp = "456"; logMessager.Show("{0}:{1}", list[0].RedisIp, items[0].RedisIp); }
注意事項:
第一種方式無需任何依賴。
第二種方式需要Newtonsoft.Json,如果項目中沒有用到它,不推薦使用這種方式。
第三種方式序要給引用類型實體加上[Serializable]特性
總結
以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對神馬文庫的支持。