当前位置: 首页 > 编程语言 > C#

C#使用表达式树实现对象复制的示例代码分享

时间:2023-04-10 18:04:18 C#

C#学习教程:C#实现对象复制使用表达式树CopyingofnullabletypesusingCommon的示例代码分享;使用系统;classProgram{staticvoidMain(string[]args){TestClassAclassA=newTestClassA(){PropA=newTestClass(){Name="cs1"},PropB="c1",PropC=1};TestClassAclassB=newTestClassA(){PropA=newTestClass(){Name="cs2"},PropB="c2",PropC=2};FastCopy.Copy(classA,classB,false);Console.WriteLine(classB.PropA?.Name+":"+classB.PropB+":"+classB.PropC);TestClassAclassC=newTestClassA(){PropA=newTestClass(){Name="cs1"}};TestClassAclassD=newTestClassA(){PropA=newTestClass(){Name="cs2"},PropB="c2",PropC=2};FastCopy.Copy(classC,classD,false);Console.WriteLine(classD.PropA?.Name+":"+classD.PropB+":"+classD.PropC);}}publicclassTestClassA{publicTestClassPropA{get;放;}公共字符串PropB{得到;放;公共诠释?PropC{得到;放;}}publicclassTestClass{publicstringName{get;使用System.Collections.Generic;使用System.Linq;使用System.Linq.Expressions;使用System.Reflection;使用静态System.Linq.Expressions.Expression;namespaceCommon{publicstaticclassFastCopy{staticConcurrentDictionarycopiers=newConcurrentDictionary();///

///复制两个同名对象的属性值////////////源对象///目标对象///当源对象属性值为null时,是否复制该值到目标对象publicstaticvoidCopy(Ssource,Ttarget,boolcopyNull=true){字符串名称=字符串。Format("{0}_{1}_{2}",typeof(S),typeof(T),copyNull);对象目标复制器;if(!copiers.TryGetValue(name,outtargetCopier)){Actioncopier=CreateCopier(copyNull);copiers.TryAdd(名称,复印机);targetCopier=复印机;}Actionaction=(Action)targetCopier;动作(来源,目标);}//////为指定的两种类型编译生成属性复制委托////////////源对象属性值为null时,是否将值复制到目标对象///privatestaticActionCreateCopier(boolcopyNull){ParameterExpressionsource=Parameter(typeof(S));ParameterExpressiontarget=Parameter(typeof(T));varsourceProps=typeof(S).GetProperties(BindingFlags.Instance|BindingFlags.Public).Where(p=>p.CanRead).ToList();vartargetProps=typeof(T).GetProperties(BindingFlags.Instance|BindingFlags.Public).Where(p=>p.CanWrite).ToList();//查找可以赋值的属性varcopyProps=targetProps.Where(tProp=>sourceProps.Where(sProp=>sProp.Name==tProp.Name//name是一致的&&(sProp.PropertyType==tProp.PropertyType//属性类型一致或||sProp.PropertyType.IsAssignableFrom(tProp.PropertyType)//源属性类型是目标属性类型的子类;eg:objecttarget=stringsource;或||(tProp.PropertyType.IsValueType&&sProp.PropertyType.IsValueType&&//属性是值类型,底层类型相同,但目标属性是可空类型eg:int?num=intnum;((tProp.PropertyType.GenericTypeArguments.Length>0?tProp.PropertyType.GenericTypeArguments[0]:tProp.PropertyType)==sProp.PropertyType)))).Count()>0);ListexpressionList=newList();foreach(varpropincopyProps){if(prop.PropertyType.IsValueType)//属性为类型{PropertyInfosProp=typeof(S).GetProperty(prop.Name);PropertyInfotProp=typeof(T).GetProperty(prop.Name);if(sProp.PropertyType==tProp.PropertyType)//属性类型一致eg:intnum=intnum;或者int?数字=整数?数;{varassign=Assign(Property(target,prop.Name),Property(source,prop.Name));表达式列表。添加(赋值);}elseif(sProp.PropertyType.GenericTypeArguments.Length<=0&&tProp.PropertyType.GenericTypeArguments.Length>0)//属性类型不一致,目标属性类型为可空类型eg:int?数字=整数;{varconvert=Convert(Expression.Property(source,prop.Name),tProp.PropertyType);varcvAssign=Assign(Expression.Property(target,prop.Name),convert);表达式列表.Add(cvAssign);}}else//属性为引用类型{varassign=Assign(Property(target,prop.Name),Property(source,prop.Name));//编译生成属性赋值语句target.{PropertyName}=source.{PropertyName};varsourcePropIsNull=Equal(Constant(null,prop.PropertyType),Property(source,prop.Name));//判断源属性值是否为Null;编译生成source.{PropertyName}==nullvarsetNull=IsTrue(Constant(copyNull));//判断是否复制Null值并编译生成copyNull==TruevarsetNullTest=IfThen(setNull,assign);varcondition=IfThenElse(sourcePropIsNull,setNullTest,assign);/***编译生成*if(source.{PropertyName}==null)*{*if(setNull)*{*target.{PropertyName}=source.{PropertyName};*}*}*else*{*target.{PropertyName}=source.{PropertyName};*}*/expressionList.Add(条件);}}varblock=Block(expressionList.ToArray());表达式>lambda=Lambda>(block,source,target);返回lambda.Compile();}}}如果完全复制,去掉逻辑判断,可以使用泛型类,而不是使用字典,可以提高性能使用系统;使用System.Linq;使用System.Linq.Expressions;使用System.Reflection;命名空间Common{publicstaticclassFastCopy{staticActionaction=CreateCopier();//////复制两个同名对象的属性值///////////源对象///目标对象///源对象属性值为空publicstaticvoidCopy(Ssource,Ttarget,boolcopyNull=true){action(source,target);}//////是指定的两种编译生成属性复制委托////////////当源对象的属性值为null时,是否将值复制到目标对象///privatestaticActionCreateCopier(){ParameterExpressionsource=Expression.Parameter(typeof(S));ParameterExpressiontarget=Expression.Parameter(typeof(T));varsourceProps=typeof(S).GetProperties(BindingFlags.Instance|BindingFlags.Public).Where(p=>p.CanRead).ToList();vartargetProps=typeof(T).GetProperties(BindingFlags.Instance|BindingFlags.Public).Where(p=>p.CanWrite).ToList();//查找可以赋值的属性varcopyProps=targetProps.Where(tProp=>sourceProps.Where(sProp=>sProp.Name==tProp.Name//name是一致的&&(sProp.PropertyType==tProp.PropertyType//属性类型一致)).Count()>0);varblock=Expression.Block(从copyProps中的p选择Expression.Assign(Expression.Property(target,p.Name),Expression.Property(source,p.Name)));Expression>lambda=Expression.Lambda>(block,source,target);返回lambda.Compile();}}}百万次耗时:100ms左右C#使用表达式树实现对象复制的示例代码到此结束。更多相关C#表达式树对象复制内容请搜索往期文章或继续浏览下方相关文章。希望大家以后多多支持!本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如有转载请注明出处: