有時候咱們想克隆一個List去作別的事,而不影響原來的List,咱們直接在list後面加上小點點,發現並無Clone這樣的擴展函數。這時候就只有本身擴展了。函數
嘗試了三種方式,測試都經過了,至於性能方面我尚未作測試。性能
1、反射測試
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 }
2、序列化(依賴Newtonsoft.Json)this
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 }
3、序列化(BinaryFormatter)spa
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 }
測試code
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 }
注意事項:orm
第一種方式無需任何依賴。blog
第二種方式須要Newtonsoft.Json,若是項目中沒有用到它,不推薦使用這種方式。it
第三種方式序要給引用類型實體加上[Serializable]特性form