前言
有時候我們想克隆一個List去做別的事,而不影響原來的List,我們直接在list后面加上小點點,發現并沒有Clone這樣的擴展函數。這時候就只有自己擴展了。
嘗試了三種方式,測試都通過了,至于性能方面我還沒有做測試。
下面話不多說了,來一起看看詳細的介紹吧
一、反射
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
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)
1
2
3
4
5
|
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)
1
2
3
4
5
6
7
8
9
10
|
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); } } |
測試
1
2
3
4
5
6
7
8
|
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]特性
總結
以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對服務器之家的支持。
原文鏈接:http://www.cnblogs.com/cglandy/p/10301548.html