C# 快速高效率复制对象另一种方式 表达式树
1、需求在代码中经常会遇到需要把对象复制一遍,或者把属性名相同的值复制一遍。 比如: Id { ; Name { ; Age { ;
</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span><span style="color: #000000;"> StudentSecond
{
</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">int</span> Id { <span style="color: #0000ff;">get</span>; <span style="color: #0000ff;">set</span><span style="color: #000000;">; }
</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">string</span> Name { <span style="color: #0000ff;">get</span>; <span style="color: #0000ff;">set</span><span style="color: #000000;">; }
</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">int</span> Age { <span style="color: #0000ff;">get</span>; <span style="color: #0000ff;">set</span><span style="color: #000000;">; }
}</span></pre>
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,Name = s.Name }; ? 2、解决办法当然最原始的办法就是把需要赋值的属性全部手动手写。这样的效率是最高的。但是这样代码的重复率太高,而且代码看起来也不美观,更重要的是浪费时间,如果一个类有几十个属性,那一个一个属性赋值岂不是浪费精力,像这样重复的劳动工作更应该是需要优化的。 2.1、反射反射应该是很多人用过的方法,就是封装一个类,反射获取属性和设置属性的值。 TOut TransReflection
调用:StudentSecond ss= TransReflection 调用一百万次耗时: 2.2、序列化序列化的方式有很多种,有二进制、xml、json等等,今天我们就用Newtonsoft的json进行测试。 调用:StudentSecond ss= JsonConvert.DeserializeObject 调用一百万次耗时: 从这可以看出序列化和反射效率差别不大。 3、表达式树3.1、简介关于表达式树不了解的可以百度。 也就是说复制对象也可以用表达式树的方式。 Expression
这样的方式我们可以达到同样的效果。 有人说这样的写法和最原始的复制没有什么区别,代码反而变多了呢,这个只是第一步。 3.2、分析代码我们用ILSpy反编译下这段表达式代码如下: 那么也就是说我们只要用反射循环所有的属性然后Expression.Bind所有的属性。最后调用Compile()(s)就可以获取正确的StudentSecond。 看到这有的人又要问了,如果用反射的话那岂不是效率很低,和直接用反射或者用序列化没什么区别吗? 当然这个可以解决的,就是我们的表达式树可以缓存。只是第一次用的时候需要反射,以后再用就不需要反射了。 3.3、复制对象通用代码为了通用性所以其中的Student和StudentSecond分别泛型替换。 Dictionary<,> _Dic = Dictionary<,>
</span><span style="color: #0000ff;">private</span> <span style="color: #0000ff;">static</span> TOut TransExp<TIn,TOut><span style="color: #000000;">(TIn tIn)
{
</span><span style="color: #0000ff;">string</span> key = <span style="color: #0000ff;">string</span>.Format(<span style="color: #800000;">"</span><span style="color: #800000;">trans_exp_{0}_{1}</span><span style="color: #800000;">"</span>,<span style="color: #0000ff;">typeof</span>(TIn).FullName,<span style="color: #0000ff;">typeof</span><span style="color: #000000;">(TOut).FullName);
</span><span style="color: #0000ff;">if</span> (!<span style="color: #000000;">_Dic.ContainsKey(key))
{
ParameterExpression parameterExpression </span>= Expression.Parameter(<span style="color: #0000ff;">typeof</span>(TIn),<span style="color: #800000;">"</span><span style="color: #800000;">p</span><span style="color: #800000;">"</span><span style="color: #000000;">);
List</span><MemberBinding> memberBindingList = <span style="color: #0000ff;">new</span> List<MemberBinding><span style="color: #000000;">();
</span><span style="color: #0000ff;">foreach</span> (<span style="color: #0000ff;">var</span> item <span style="color: #0000ff;">in</span> <span style="color: #0000ff;">typeof</span><span style="color: #000000;">(TOut).GetProperties())
{ </span> if (!item.CanWrite) continue;?</pre>
= Expression.Property(parameterExpression,=
调用:StudentSecond ss= TransExp 调用一百万次耗时: 3.4、利用泛型的特性再次优化代码
<div class="cnblogs_code"> TransExpV2
调用:StudentSecond ss= TransExpV2 调用一百万次耗时:
4、总结效率与书写方式二者兼备的方法之一,总之比传统的序列化和反射更加优秀。 推荐。 ? (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- 深入理解C#3.x的新特性(4):Automatically Implemented P
- Asp.Net 文件操作基类(读取,删除,批量拷贝,删除,写入,获取文
- asp.net – aspx radiobutton控制列表在一行中
- asp.net – foreach块缺少一个结束“}”字符.确保你有匹配的
- asp.net – OutputCache和RenderAction缓存整个页面
- asp.net – DataSet.GetXml没有返回null结果
- asp.net – JSON字符串中的反斜杠
- 如何配置ASP.NET OutputCache与http vs https不同?
- asp.net-mvc-2 – 为什么mvc Html.HiddenFor不渲染我的字段
- ASP.Net vnext api在localhost上工作,在azure上返回404
- asp.net-mvc – ASP.NET MVC PostAuthorizeReque
- asp.net – 配置部分不能在web.config文件中包含
- asp.net – 通过sql servers SP在aspnet成员中添
- asp.net-mvc – 如何包括一个模型与RedirectToAc
- asp.net – asp图表错误
- asp.net-mvc – Asp.net MVC查看测试?
- asp.net-mvc-3 – 返回404错误ASP.NET MVC 3
- asp.net-mvc – 有没有一种很好的方法将ASP.NET身
- asp.net-mvc – 调试流畅的验证规则
- asp.net-mvc-3 – MVC3下拉列表未选择所选项目