亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C# > 正文

C# 快速高效率復制對象(表達式樹)

2019-10-29 21:11:47
字體:
來源:轉載
供稿:網友

1、需求

在代碼中經常會遇到需要把對象復制一遍,或者把屬性名相同的值復制一遍。

比如:

public class Student {  public int Id { get; set; }  public string Name { get; set; }   public int Age { get; set; }  } public class StudentSecond {  public int Id { get; set; }  public string Name { get; set; }  public int Age { get; set; }  }

Student s = new Student() { Age = 20, Id = 1, Name = "Emrys" };

我們需要給新的Student賦值

Student ss = new Student { Age = s.Age, Id = s.Id, Name = s.Name };

再或者給另一個類StudentSecond的屬性賦值,兩個類屬性的名稱和類型一致。

StudentSecond ss = new StudentSecond { Age = s.Age, Id = s.Id, Name = s.Name };

2、解決辦法

當然最原始的辦法就是把需要賦值的屬性全部手動手寫。這樣的效率是最高的。但是這樣代碼的重復率太高,而且代碼看起來也不美觀,更重要的是浪費時間,如果一個類有幾十個屬性,那一個一個屬性賦值豈不是浪費精力,像這樣重復的勞動工作更應該是需要優化的。

2.1、反射

反射應該是很多人用過的方法,就是封裝一個類,反射獲取屬性和設置屬性的值。

private static TOut TransReflection<TIn, TOut>(TIn tIn)  {   TOut tOut = Activator.CreateInstance<TOut>();   foreach (var itemOut in tOut.GetType().GetProperties())   {    var itemIn = tIn.GetType().GetProperties().Where(i => i.Name == itemOut.Name).FirstOrDefault();    if (itemIn != null)    {     itemOut.SetValue(tOut, itemIn.GetValue(tIn));    }   }   return tOut;  }

調用:StudentSecond ss= TransReflection<Student, StudentSecond>(s);

調用一百萬次耗時:2464毫秒

2.2、序列化

序列化的方式有很多種,有二進制、xml、json等等,今天我們就用Newtonsoft的json進行測試。

調用:

StudentSecond ss= JsonConvert.DeserializeObject<StudentSecond>(JsonConvert.SerializeObject(s));

調用一百萬次耗時:2984毫秒

從這可以看出序列化和反射效率差別不大。

3、表達式樹

3.1、簡介

關于表達式樹不了解的可以百度。

也就是說復制對象也可以用表達式樹的方式。

  Expression<Func<Student, StudentSecond>> ss = (x) => new StudentSecond { Age = x.Age, Id = x.Id, Name = x.Name };  var f = ss.Compile();  StudentSecond studentSecond = f(s);

這樣的方式我們可以達到同樣的效果。

有人說這樣的寫法和最原始的復制沒有什么區別,代碼反而變多了呢,這個只是第一步。

3.2、分析代碼

我們用ILSpy反編譯下這段表達式代碼如下:

ParameterExpression parameterExpression; Expression<Func<Student, StudentSecond>> ss = Expression.Lambda<Func<Student, StudentSecond>>(Expression.MemberInit(Expression.New(typeof(StudentSecond)), new MemberBinding[] {  Expression.Bind(methodof(StudentSecond.set_Age(int)), Expression.Property(parameterExpression, methodof(Student.get_Age()))),  Expression.Bind(methodof(StudentSecond.set_Id(int)), Expression.Property(parameterExpression, methodof(Student.get_Id()))),  Expression.Bind(methodof(StudentSecond.set_Name(string)), Expression.Property(parameterExpression, methodof(Student.get_Name()))) }), new ParameterExpression[] {  parameterExpression }); Func<Student, StudentSecond> f = ss.Compile(); StudentSecond studentSecond = f(s);

那么也就是說我們只要用反射循環所有的屬性然后Expression.Bind所有的屬性。最后調用Compile()(s)就可以獲取正確的StudentSecond。

看到這有的人又要問了,如果用反射的話那豈不是效率很低,和直接用反射或者用序列化沒什么區別嗎?

當然這個可以解決的,就是我們的表達式樹可以緩存。只是第一次用的時候需要反射,以后再用就不需要反射了。

3.3、復制對象通用代碼

為了通用性所以其中的Student和StudentSecond分別泛型替換。

private static Dictionary<string, object> _Dic = new Dictionary<string, object>();  private static TOut TransExp<TIn, TOut>(TIn tIn)  {   string key = string.Format("trans_exp_{0}_{1}", typeof(TIn).FullName, typeof(TOut).FullName);   if (!_Dic.ContainsKey(key))   {    ParameterExpression parameterExpression = Expression.Parameter(typeof(TIn), "p");    List<MemberBinding> memberBindingList = new List<MemberBinding>();    foreach (var item in typeof(TOut).GetProperties())    {     MemberExpression property = Expression.Property(parameterExpression, typeof(TIn).GetProperty(item.Name));     MemberBinding memberBinding = Expression.Bind(item, property);     memberBindingList.Add(memberBinding);    }    MemberInitExpression memberInitExpression = Expression.MemberInit(Expression.New(typeof(TOut)), memberBindingList.ToArray());    Expression<Func<TIn, TOut>> lambda = Expression.Lambda<Func<TIn, TOut>>(memberInitExpression, new ParameterExpression[] { parameterExpression });    Func<TIn, TOut> func = lambda.Compile();    _Dic[key] = func;   }   return ((Func<TIn, TOut>)_Dic[key])(tIn);  }

調用:StudentSecond ss= TransExp<Student, StudentSecond>(s);

調用一百萬次耗時:564毫秒

4、總結

從以上的測試和分析可以很容易得出,用表達式樹是可以達到效率與書寫方式二者兼備的方法之一,總之比傳統的序列化和反射更加優秀。

以上就是本文的全部內容,希望本文的內容對大家的學習或者工作能帶來一定的幫助,同時也希望多多支持VEVB武林網!


注:相關教程知識閱讀請移步到c#教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产成+人+综合+亚洲欧洲| 久久久之久亚州精品露出| 国产日韩欧美视频| 亚洲高清免费观看高清完整版| 欧美一级黄色网| 成人网在线视频| 91精品视频免费| 热re91久久精品国99热蜜臀| 中文字幕精品一区二区精品| 怡红院精品视频| 亚洲精品国产精品国产自| 97在线精品国自产拍中文| 美女福利视频一区| 成人在线激情视频| 日韩视频亚洲视频| 国产成人+综合亚洲+天堂| 久久夜色撩人精品| 亚洲一区二区三区四区视频| 欧美综合第一页| 91亚洲一区精品| 欧美激情a∨在线视频播放| 草民午夜欧美限制a级福利片| 亚洲精品aⅴ中文字幕乱码| 欧美精品videosex性欧美| 91在线观看免费| 国产一区二区激情| 精品久久久久久久大神国产| 国产精品入口日韩视频大尺度| 这里只有精品在线观看| 欧美俄罗斯乱妇| 91av在线看| 久久夜色精品国产| 欧美日韩国产在线看| 国产精品爽黄69天堂a| 日韩av高清不卡| 亚洲美女又黄又爽在线观看| 亚洲国产精品一区二区久| 91欧美视频网站| xvideos亚洲| 国产精品入口免费视频一| 中文字幕欧美国内| 亚洲国产精品va在线看黑人| 久久视频在线直播| 91老司机精品视频| 狠狠色香婷婷久久亚洲精品| 国产日韩欧美自拍| 亚洲乱码国产乱码精品精| 91亚洲精品在线观看| 欧美一区二三区| 欧美成人三级视频网站| 欧美成人性色生活仑片| 日韩av色综合| 中文字幕欧美亚洲| 91av在线国产| 亚洲欧洲在线免费| 欧洲中文字幕国产精品| 欧美丝袜第一区| 欧美性猛交xxxx乱大交| 亚洲www在线| 国产精品激情av电影在线观看| 美女久久久久久久久久久| 亚洲精品美女久久久久| 日韩免费在线电影| 日韩美女在线观看一区| 精品电影在线观看| 日韩美女福利视频| 国产精品久久久久久久久免费看| 亚洲v日韩v综合v精品v| 国产精品十八以下禁看| 欧美精品www在线观看| 欧美成人剧情片在线观看| 成人激情免费在线| 日韩av网站电影| 日韩精品视频中文在线观看| 91精品国产综合久久香蕉| 欧美性生交大片免费| 欧美激情a∨在线视频播放| 久久久www成人免费精品张筱雨| 日韩在线不卡视频| 欧美疯狂做受xxxx高潮| 日韩精品免费在线播放| 亚洲自拍偷拍色片视频| 亚洲视频在线免费看| 亚洲缚视频在线观看| 日韩在线观看高清| 精品成人国产在线观看男人呻吟| 日本高清久久天堂| 国产精品入口福利| 中文字幕亚洲欧美一区二区三区| 日韩亚洲国产中文字幕| 九九久久精品一区| 国产精品ⅴa在线观看h| 亚洲免费电影在线观看| 精品美女久久久久久免费| 亚洲欧美福利视频| 日本亚洲欧洲色α| 羞羞色国产精品| 中文字幕欧美精品在线| 亚洲欧美在线一区| 欧美日韩第一页| 91在线视频免费| 国产精品久久久久久五月尺| 亚洲国产精品专区久久| 欧美—级a级欧美特级ar全黄| 欧美精品一区三区| 4p变态网欧美系列| 亚洲尤物视频网| 亚洲人在线视频| 成人乱人伦精品视频在线观看| 日韩有码片在线观看| 日本aⅴ大伊香蕉精品视频| 国产成人自拍视频在线观看| 日本午夜在线亚洲.国产| 亚洲最大成人网色| 亚洲精品小视频在线观看| 亚洲最新视频在线| 亚洲欧美国产一本综合首页| 亚洲四色影视在线观看| 久久久久99精品久久久久| 国产精品三级美女白浆呻吟| 欧美综合一区第一页| 亚洲大胆人体视频| 亚洲女人天堂色在线7777| 亚洲最大福利网| 国产精品自在线| 国产视频精品va久久久久久| 亚洲一品av免费观看| 91精品国产91久久久久久不卡| 亚洲精品短视频| 欧美精品18videosex性欧美| 亚洲美女福利视频网站| 日韩欧美在线视频日韩欧美在线视频| 国产亚洲免费的视频看| 亚洲电影免费观看高清| 久久免费视频在线| 久久精品久久精品亚洲人| 不卡av电影在线观看| 久久久国产精品免费| 欧美激情手机在线视频| 成人免费大片黄在线播放| 97人洗澡人人免费公开视频碰碰碰| 亚洲社区在线观看| 久久亚洲精品网站| 欧美日本在线视频中文字字幕| 538国产精品一区二区在线| 欧美成人国产va精品日本一级| 成人精品一区二区三区电影黑人| 狠狠色狠狠色综合日日小说| 国产精品福利网| 国产69精品99久久久久久宅男| 中文字幕国产亚洲2019| 国产专区欧美专区| 国产一区二区香蕉| 91久久久久久久| 国产精品国产三级国产aⅴ浪潮| 国产精品久久久久免费a∨大胸| 亚洲天堂一区二区三区| 一区二区欧美日韩视频| 久久精视频免费在线久久完整在线看| 国产精品久久综合av爱欲tv| 国产精品第七影院| 亚洲精品在线不卡| 69久久夜色精品国产69| 97视频免费在线观看|