在C#中实现两个对象部分相同属性值的复制,可通过以下方案实现:
一、手动赋值(基础方案)
直接通过属性名逐个赋值,适用于属性较少且明确的情况:
// 示例类定义
public class Source
{
public int Id { get; set; }
public string Name { get; set; }
}
public class Target
{
public int Id { get; set; }
public string Name { get; set; }
}
// 手动赋值
var source = new Source { Id = 1, Name = "Test" };
var target = new Target
{
Id = source.Id,
Name = source.Name
};
特点:性能最优但代码冗余。
二、反射实现(通用方案)
通过反射动态匹配同名属性,适用于属性较多或动态场景:
public static void CopyProperties(object source, object target)
{
var sourceType = source.GetType();
var targetType = target.GetType();
foreach (var prop in sourceType.GetProperties())
{
var targetProp = targetType.GetProperty(prop.Name);
if (targetProp != null && targetProp.PropertyType == prop.PropertyType)
{
targetProp.SetValue(target, prop.GetValue(source));
}
}
}
// 调用示例
CopyProperties(source, target);
注意事项:
1、需处理属性类型是否兼容(如可空类型)。
2、反射性能较低,频繁调用需谨慎。
三、使用 AutoMapper(第三方库)
通过 AutoMapper 库简化映射逻辑:
// 安装 NuGet 包:Install-Package AutoMapper
var config = new MapperConfiguration(cfg =>
cfg.CreateMap<Source, Target>()
// 可选:忽略特定属性
.ForMember(dest => dest.IgnoreProp, opt => opt.Ignore())
);
var mapper = config.CreateMapper();
Target target = mapper.Map<Target>(source);
优点:代码简洁,支持复杂映射配置。
四、表达式树实现(高性能方案)
通过预编译表达式树提升性能,适合高频调用场景:
public static class FastCopy
{
private static Dictionary<string, Action<object, object>> _cache = new();
public static void Copy(object source, object target)
{
var key = $"{source.GetType().FullName}_{target.GetType().FullName}";
if (!_cache.TryGetValue(key, out var copyAction))
{
copyAction = BuildCopyAction(source.GetType(), target.GetType());
_cache[key] = copyAction;
}
copyAction(source, target);
}
private static Action<object, object> BuildCopyAction(Type sourceType, Type targetType)
{
// 构建表达式树(略,详见引用[7])
// 返回编译后的委托
}
}
特点:接近原生代码性能,但实现复杂度较高。
方案对比
方法 性能 编码复杂度 适用场景
手动赋值 最高 低 少量固定属性
反射 低 中 动态属性匹配
AutoMapper 中 低 需要灵活配置或复杂映射
表达式树 高 高 高频调用且追求性能优化
推荐选择:
简单场景优先手动赋值或 AutoMapper。
高频调用场景建议采用表达式树预编译方案。
如果您喜欢此文章,请收藏、点赞、评论,谢谢,祝您快乐每一天。