.NET/C#中是否有内置用于在对象之间复制值?

luc*_*iet 10 .net c# copy

假设您有2个类,如下所示:

public class ClassA {
    public int X { get; set; }
    public int Y { get; set; }
    public int Other { get; set; }
}

public class ClassB {
    public int X { get; set; }
    public int Y { get; set; }
    public int Nope { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

现在假设您有一个每个类的实例,并且您想要将值从a复制到b中.有没有类似于MemberwiseClone的东西会复制属性名称匹配的值(当然是容错的 - 一个有get,另一个有set等)?

var a = new ClassA(); var b = new classB();
a.CopyTo(b); // ??
Run Code Online (Sandbox Code Playgroud)

像JavaScript这样的语言很容易.

我猜答案是否定的,但也许有一个简单的替代方案.我已经编写了一个反射库来执行此操作,但如果内置于较低级别的C#/ .NET可能会更有效(以及为什么重新发明轮子).

Ani*_*Ani 10

框架中没有任何对象 - 对象映射,但有一个非常流行的库可以做到这一点: AutoMapper.

AutoMapper是一个简单的小型库,用于解决一个看似复杂的问题 - 摆脱将一个对象映射到另一个对象的代码.这种类型的代码是相当沉闷和无聊的写,所以为什么不发明一个工具来为我们做?

顺便说一下,只是为了学习,这里有一个简单的方法可以实现你想要的.我没有对它进行彻底的测试,而且它没有AutoMapper那样强大/灵活/高效,但希望有一些东西可以摆脱一般的想法:

public void CopyTo(this object source, object target)
{
    // Argument-checking here...

    // Collect compatible properties and source values
    var tuples = from sourceProperty in source.GetType().GetProperties()
                 join targetProperty in target.GetType().GetProperties() 
                                     on sourceProperty.Name 
                                     equals targetProperty.Name

                 // Exclude indexers
                 where !sourceProperty.GetIndexParameters().Any()
                    && !targetProperty.GetIndexParameters().Any()

                 // Must be able to read from source and write to target.
                 where sourceProperty.CanRead && targetProperty.CanWrite

                 // Property types must be compatible.
                 where targetProperty.PropertyType
                                     .IsAssignableFrom(sourceProperty.PropertyType)

                 select new
                 {
                     Value = sourceProperty.GetValue(source, null),
                     Property = targetProperty
                 };

    // Copy values over to target.
    foreach (var valuePropertyTuple in tuples)
    {
        valuePropertyTuple.Property
                          .SetValue(target, valuePropertyTuple.Value, null);

    }
}
Run Code Online (Sandbox Code Playgroud)