C#使用表达式树怎么实现对象复制
发表于:2026-11-03 作者:千家信息网编辑
千家信息网最后更新 2026年11月03日,本篇内容主要讲解"C#使用表达式树怎么实现对象复制",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"C#使用表达式树怎么实现对象复制"吧!需求背景:对象复制性
千家信息网最后更新 2026年11月03日C#使用表达式树怎么实现对象复制
本篇内容主要讲解"C#使用表达式树怎么实现对象复制",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"C#使用表达式树怎么实现对象复制"吧!
需求背景:对象复制性能优化;同时,在对象复制时,应跳过引用类型的null值复制,值类型支持值类型向可空类型的复制
using Common;using System;class Program{ static void Main(string[] args) { TestClassA classA = new TestClassA() { PropA = new TestClass() { Name = "cs1" }, PropB = "c1", PropC = 1 }; TestClassA classB = new TestClassA() { PropA = new TestClass() { Name = "cs2" }, PropB = "c2", PropC = 2 }; FastCopy.Copy(classA, classB, false); Console.WriteLine(classB.PropA?.Name + ":" + classB.PropB + ":" + classB.PropC); TestClassA classC = new TestClassA() { PropA = new TestClass() { Name = "cs1" } }; TestClassA classD = new TestClassA() { PropA = new TestClass() { Name = "cs2" }, PropB = "c2", PropC = 2 }; FastCopy.Copy(classC, classD, false); Console.WriteLine(classD.PropA?.Name + ":" + classD.PropB + ":" + classD.PropC); }}public class TestClassA{ public TestClass PropA { get; set; } public string PropB { get; set; } public int? PropC { get; set; }}public class TestClass{ public string Name { get; set; }}输出:

百万次调用耗时:270-300ms
using System;using System.Collections.Concurrent;using System.Collections.Generic;using System.Linq;using System.Linq.Expressions;using System.Reflection;using static System.Linq.Expressions.Expression;namespace Common{ public static class FastCopy { static ConcurrentDictionary copiers = new ConcurrentDictionary(); /// /// 复制两个对象同名属性值 /// /// /// /// 源对象 /// 目标对象 /// 源对象属性值为null时,是否将值复制给目标对象 public static void Copy(S source, T target, bool copyNull = true) { string name = string.Format("{0}_{1}_{2}", typeof(S), typeof(T), copyNull); object targetCopier; if (!copiers.TryGetValue(name, out targetCopier)) { Action copier = CreateCopier(copyNull); copiers.TryAdd(name, copier); targetCopier = copier; } Action action = (Action)targetCopier; action(source, target); } /// /// 为指定的两种类型编译生成属性复制委托 /// /// /// /// 源对象属性值为null时,是否将值复制给目标对象 /// private static Action CreateCopier(bool copyNull) { ParameterExpression source = Parameter(typeof(S)); ParameterExpression target = Parameter(typeof(T)); var sourceProps = typeof(S).GetProperties(BindingFlags.Instance | BindingFlags.Public).Where(p => p.CanRead).ToList(); var targetProps = typeof(T).GetProperties(BindingFlags.Instance | BindingFlags.Public).Where(p => p.CanWrite).ToList(); // 查找可进行赋值的属性 var copyProps = targetProps.Where(tProp => sourceProps.Where(sProp => sProp.Name == tProp.Name// 名称一致 且 && ( sProp.PropertyType == tProp.PropertyType// 属性类型一致 或 || sProp.PropertyType.IsAssignableFrom(tProp.PropertyType) // 源属性类型 为 目标属性类型 的 子类;eg:object target = string source; 或 || (tProp.PropertyType.IsValueType && sProp.PropertyType.IsValueType && // 属性为值类型且基础类型一致,但目标属性为可空类型 eg:int? num = int num; ((tProp.PropertyType.GenericTypeArguments.Length > 0 ? tProp.PropertyType.GenericTypeArguments[0] : tProp.PropertyType) == sProp.PropertyType)) )).Count() > 0); List expressionList = new List(); foreach (var prop in copyProps) { if (prop.PropertyType.IsValueType)// 属性为值类型 { PropertyInfo sProp = typeof(S).GetProperty(prop.Name); PropertyInfo tProp = typeof(T).GetProperty(prop.Name); if (sProp.PropertyType == tProp.PropertyType)// 属性类型一致 eg:int num = int num; 或 int? num = int? num; { var assign = Assign(Property(target, prop.Name), Property(source, prop.Name)); expressionList.Add(assign); } else if (sProp.PropertyType.GenericTypeArguments.Length <= 0 && tProp.PropertyType.GenericTypeArguments.Length > 0)// 属性类型不一致且目标属性类型为可空类型 eg:int? num = int num; { var convert = Convert(Expression.Property(source, prop.Name), tProp.PropertyType); var cvAssign = Assign(Expression.Property(target, prop.Name), convert); expressionList.Add(cvAssign); } } else// 属性为引用类型 { var assign = Assign(Property(target, prop.Name), Property(source, prop.Name));// 编译生成属性赋值语句 target.{PropertyName} = source.{PropertyName}; var sourcePropIsNull = Equal(Constant(null, prop.PropertyType), Property(source, prop.Name));// 判断源属性值是否为Null;编译生成 source.{PropertyName} == null var setNull = IsTrue(Constant(copyNull));// 判断是否复制Null值 编译生成 copyNull == True var setNullTest = IfThen(setNull, assign); var condition = IfThenElse(sourcePropIsNull, setNullTest, assign); /** * 编译生成 * if(source.{PropertyName} == null) * { * if(setNull) * { * target.{PropertyName} = source.{PropertyName}; * } * } * else * { * target.{PropertyName} = source.{PropertyName}; * } */ expressionList.Add(condition); } } var block = Block(expressionList.ToArray()); Expression> lambda = Lambda>(block, source, target); return lambda.Compile(); } }} 如果完整复制,去掉逻辑判断,同时可通过泛型类,不在使用字典,性能还可以提升。
using System;using System.Linq;using System.Linq.Expressions;using System.Reflection;namespace Common{ public static class FastCopy { static Action action = CreateCopier(); /// /// 复制两个对象同名属性值 /// /// /// /// 源对象 /// 目标对象 /// 源对象属性值为null时,是否将值复制给目标对象 public static void Copy(S source, T target, bool copyNull = true) { action(source, target); } /// /// 为指定的两种类型编译生成属性复制委托 /// /// /// /// 源对象属性值为null时,是否将值复制给目标对象 /// private static Action CreateCopier() { ParameterExpression source = Expression.Parameter(typeof(S)); ParameterExpression target = Expression.Parameter(typeof(T)); var sourceProps = typeof(S).GetProperties(BindingFlags.Instance | BindingFlags.Public).Where(p => p.CanRead).ToList(); var targetProps = typeof(T).GetProperties(BindingFlags.Instance | BindingFlags.Public).Where(p => p.CanWrite).ToList(); // 查找可进行赋值的属性 var copyProps = targetProps.Where(tProp => sourceProps.Where(sProp => sProp.Name == tProp.Name// 名称一致 且 && ( sProp.PropertyType == tProp.PropertyType// 属性类型一致 )).Count() > 0); var block = Expression.Block(from p in copyProps select Expression.Assign(Expression.Property(target, p.Name), Expression.Property(source, p.Name))); Expression> lambda = Expression.Lambda>(block, source, target); return lambda.Compile(); } }} 百万次耗时:100ms左右
到此,相信大家对"C#使用表达式树怎么实现对象复制"有了更深的了解,不妨来实际操作一番吧!这里是网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!
属性
对象
类型
目标
一致
生成
编译
表达式
C#
两个
内容
同时
名称
性能
委托
学习
实用
更深
兴趣
基础
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
中国互联网科技工作委员会毛军
万易互联网科技
美国互联网科技
迪茉互联网科技
极限挑战互联网科技
猫创互联网科技
盛创互联网科技有限公司
哈尔滨新华互联网科技学院
华服互联网科技官网
贵州叶脉互联网科技有限公司所属行业
互联网软件和科技
语蝶互联网科技有限公司
996高科技互联网公司
威龙国际互联网科技公司
互联网与数字科技关系
郑州欣桑互联网科技有限公司
2021世界互联网领先科技成果发布
科技互联网行业投资研究
北京品多多互联网科技有限公司
前海云享互联网科技
互联网新科技
互联网医疗科技
互联网科技股票
世界互联网领先科技成果
睿民互联网科技
互联网教育科技公司vipkid
岳阳华臻互联网科技有限公司
语蝶互联网科技有限公司
赶超互联网科技 微信多开
畅思互联网科技