How to copy data from different classes by matching fields or property names

I am looking to find a way to take two objects that have identical properties, and make a call to copy property values ​​from one object to another. In the example below, suppose I have an instance of A, and I want to use the data of this instance to hydrate a new instance or C (to keep something short, I used fields instead of properties in the example below)

public class A : B
{
    public string prop1;
    public int prop2;
}

public class B
{
    public byte propX;
    public float propY;
}

public class C
{
    public byte propX;
    public float propY;
    public string prop1;
    public int prop2;
}

public class Merger
{
    public static object Merge(object copyFrom, object copyTo)
    { 
        //do some work
        //maybe <T> generically refactor?
    }
}

The merge class is just an example of psuedo, so doing this with generics will be optimal, but the first thing I ask is whether there is such a possibility. I could have imagined that I was doing it myself by reflection, but I just wanted to throw it away for the best ideas first.

: , MVVM, , EF, ViewModel.

+3
4

, AutoMapper - - ! - !: -)

A C :

Mapper.CreateMap<A, C>();

AutoMapper A C, - :

C yourC = Mapper.Map<A, C>(instanceOfA);

AutoMapper , ( ) , , ( ) 100%. - !

+8
using System;
using System.Linq;
using System.Reflection;

public class Merger
{
    public static TTarget Merge<TTarget>(object copyFrom) where TTarget : new()
    {
        var flags = BindingFlags.Instance | BindingFlags.Public |
                    BindingFlags.NonPublic;
        var targetDic = typeof(TTarget).GetFields(flags)
                                       .ToDictionary(f => f.Name);
        var ret = new TTarget();
        foreach (var f in copyFrom.GetType().GetFields(flags))
        {
            if (targetDic.ContainsKey(f.Name))
                targetDic[f.Name].SetValue(ret, f.GetValue(copyFrom));
            else
                throw new InvalidOperationException(string.Format(
                    "The field "{0}" has no corresponding field in the type "{1}".",
                    f.Name, typeof(TTarget).FullName));
        }
        return ret;
    }
}

class Program
{
    static void Main(string[] args)
    {
        var a = new A { prop1 = "one", prop2 = 2, propX = 127, propY = 0.47f };
        var c = Merger.Merge<C>(a);
        Console.WriteLine(c.prop1);  // prints one
        Console.WriteLine(c.prop2);  // prints 2
        Console.WriteLine(c.propX);  // prints 127
        Console.WriteLine(c.propY);  // prints 0.47
    }
}
+1

, , , XML XML XML .

Merger :

public class Merger
{
    public static object Merge(object copyFrom, object copyTo)
    { 
        var xmlContent = MyXMLSerializationMethod(copyFrom);
        MyXMLDeserializationMethod(xmlContent, typeof(copyTo), out copyTo);
        return copyTo;
    }
}
0

Source: https://habr.com/ru/post/1764407/


All Articles