使用C#将属性值复制到另一个对象

Ric*_*cky 21 c#

要将属性值从一个对象复制到另一个对象,我们通常使用以下语法实现:

ca.pro1 = cb.pro2;
ca.pro2 = cb.pro2;
Run Code Online (Sandbox Code Playgroud)

其中ca和cb属于同一类.

有没有更简单的synatx或实用方法来帮助我们达到同样的效果?

谢谢.

Yar*_*icx 30

public static void CopyPropertiesTo<T, TU>(this T source, TU dest)
{
    var sourceProps = typeof (T).GetProperties().Where(x => x.CanRead).ToList();
    var destProps = typeof(TU).GetProperties()
            .Where(x => x.CanWrite)
            .ToList();

    foreach (var sourceProp in sourceProps)
    {
        if (destProps.Any(x => x.Name == sourceProp.Name))
        {
            var p = destProps.First(x => x.Name == sourceProp.Name);
            if(p.CanWrite) { // check if the property can be set or no.
                p.SetValue(dest, sourceProp.GetValue(source, null), null);
            }
        }

    }

}
Run Code Online (Sandbox Code Playgroud)

  • 为什么`if(p.CanWrite)`?destProps已经是CanWrite类型. (5认同)
  • 你可以这样优化: `var p = destProps.FirstOrDefault(x =&gt; x.Name == sourceProp.Name);` `if (p != null)` `p.SetValue(dest, sourceProp.GetValue(source,空),空);` (2认同)

Pie*_*ant 10

这是我用来在ASP.NET MVC中的模型之间复制成员的函数.当您寻找适用于相同类型的代码时,此代码也将支持具有相同属性的其他类型.

它使用反射,但以更干净的方式.谨防Convert.ChangeType:你可能不需要它; 你可以检查类型而不是转换.

public static TConvert ConvertTo<TConvert>(this object entity) where TConvert : new()
{
    var convertProperties = TypeDescriptor.GetProperties(typeof(TConvert)).Cast<PropertyDescriptor>();
    var entityProperties = TypeDescriptor.GetProperties(entity).Cast<PropertyDescriptor>();

    var convert = new TConvert();

    foreach (var entityProperty in entityProperties)
    {
        var property = entityProperty;
        var convertProperty = convertProperties.FirstOrDefault(prop => prop.Name == property.Name);
        if (convertProperty != null)
        {
            convertProperty.SetValue(convert, Convert.ChangeType(entityProperty.GetValue(entity), convertProperty.PropertyType));
        }
    }

    return convert;
}
Run Code Online (Sandbox Code Playgroud)

由于这是一种扩展方法,因此用法很简单:

var result = original.ConvertTo<SomeOtherType>();
Run Code Online (Sandbox Code Playgroud)


ste*_*nly 6

如果我没有弄错所需,那么在两个现有实例(即使不是同一类型)之间轻松实现属性值复制的方法是使用 Automapper.

  1. 创建映射配置
  2. 然后调用.Map(soure,target)

只要你保持属性在相同的类型和相同的命名约定中,所有都应该工作.

例:

MapperConfiguration _configuration = new MapperConfiguration(cnf =>
            {
                cnf.CreateMap<SourceType, TargetType>();
            });
var mapper = new Mapper(_configuration);
maper.DefaultContext.Mapper.Map(source, target)
Run Code Online (Sandbox Code Playgroud)


Sco*_* M. 3

并不真地。有一个MemberwiseClone()但直接复制引用意味着您将获得对同一对象的引用,这可能很糟糕。您可以实现ICloneable接口并将其用于深层复制。不过,我更喜欢创建自己的 Clone() 方法,因为 ICloneable 接口返回一个需要强制转换的对象。

  • 我不会为 ICloneable 烦恼,不可能正确实现它,因为该接口不允许调用者表明他所说的“克隆”的含义。 (3认同)