将属性从对象复制到另一个对象的优雅方式
本文关键字:一个对象 方式 属性 对象 复制 | 更新日期: 2023-09-27 18:35:25
我有一个小型集成服务,它接收XML文件并对其进行解析。此外,我还从提供的 XSD 创建了用于反序列化 XML 数据的类。在解析过程中,我需要将属性从这些 XSD 生成的类复制到我在数据层中使用的我自己的类。这是我的一个例子
var supplierInfo = new SupplierInfo();
//coping properties
supplierInfo.Name = supplier.name;
supplierInfo.ShortName = supplier.shortName;
supplierInfo.BrandName = supplier.brandName;
supplierInfo.AdditionalFullName = supplier.additionalFullName;
supplierInfo.AdditionalCode = supplier.additionalCode;
supplierInfo.AdditionalInfo = supplier.additionalInfo;
//lot's of other properties
//...
supplierInfo.Tax = supplier.tax;
supplierInfo.RegistrationDate = supplier.registrationDate;
有时房产的面积非常大。是否有更合适的方法来复制这些属性?
Automapper自古以来就已经存在了。久经考验。http://automapper.org/
下面是一个示例:
using System;
using AutoMapper;
public class Program
{
class SupplierInfo
{
public SupplierInfo( string name, string shortName, string brandName ) {
Name = name;
ShortName = shortName;
BrandName = brandName;
}
public string Name {get; private set; }
public string ShortName {get; private set; }
public string BrandName {get; private set; }
}
class Supplier
{
public string name {get; set; }
public string shortName {get; set; }
public string brandName {get; set; }
}
public static void Main()
{
var dto = new Supplier() {
name = "Name 1",
shortName = "Short Name 1",
brandName = "Brand Name 1"
};
//From the tutorial:
//You only need one MapperConfiguration instance typically per AppDomain and should be instantiated during startup.
var config = new MapperConfiguration(cfg => cfg.CreateMap<Supplier, SupplierInfo>());
var mapper = config.CreateMapper();
SupplierInfo info = mapper.Map<SupplierInfo>(dto);
Console.WriteLine( info.Name );
Console.WriteLine( info.ShortName );
Console.WriteLine( info.BrandName );
}
}
官方入门指南可在以下位置找到 https://github.com/AutoMapper/AutoMapper/wiki/Getting-started
我很高兴对此
得到纠正,但我总是发现自动映射器(根据另一个答案),它按名称/约定映射属性值,在生产代码中使用有点吓人。
我真的没有一个像样的替代方案,但我更喜欢根据您的代码示例手动执行此操作 - 它更易于阅读和调试,如果您最终重命名类中的任何属性,很明显复制代码已损坏(或者如果您使用某些 IDE 工具重命名属性, 它会相应地更改复制代码)。
首先,安装 EntityLite.Core:
PM> Install-Package EntityLite.Core
然后使用它:
using inercya.EntityLite.Extensions;
...
supplierInfo.AssignPropertiesFrom(supplier);
EntityLite是我开发的微型ORM。它有一些小宝石:-)
编辑:
我猜您可能不想安装EntityLite.Core
只是为了将某些属性从一个对象复制到另一个对象。因此,这里有使用反射AssignPropertiesFrom
扩展方法的实现:
public static class ObjectExtensions
{
public static void AssignPropertiesForm(this object target, object source)
{
if (target == null || source == null) throw new ArgumentNullException();
var targetPropertiesDic = target.GetType().GetProperties().Where(p => p.CanWrite).ToDictionary(p => p.Name, StringComparer.CurrentCultureIgnoreCase);
foreach (var sourceProp in source.GetType().GetProperties().Where(p => p.CanRead))
{
PropertyInfo targetProp;
if (targetPropertiesDic.TryGetValue(sourceProp.Name, out targetProp))
{
targetProp.SetValue(target, sourceProp.GetValue(source, null), null);
}
}
}
}
顺便说一下,这不是EntityLite实现。EntityLite 使用动态 IL 生成。