Johan
Johan

Reputation: 35194

Mapping values between 2 objects, without using external frameworks

I want to map all properties that match between two class instances.

public class Foo
{
    public bool A { get: set: }
    public bool B { get: set: }
    public bool C { get: set: }
    public bool D { get: set: }
    public bool E { get: set: }
}

public class Bar
{
    public bool A { get: set: }
    public bool B { get: set: }
}

Bar bar = new Bar();
bar.A = true;
bar.B = true;

How do I map the values from the bar instance to a new instance of foo (setting the properties "A" and "B" to true)? I tried to make a method for it, but i get the exception Property set method not found..

public static void MapObjectPropertyValues(object e1, object e2)
    {
        foreach (var p in e1.GetType().GetProperties())
        {
            if (e2.GetType().GetProperty(p.Name) != null)
            {
                p.SetValue(e1, e2.GetType().GetProperty(p.Name).GetValue(e2, null), null);
            }   

        }
    }

Any help is much appreciated, thanks!

Upvotes: 1

Views: 818

Answers (1)

I've implemented something similar to this before by abstracting the common properties into interfaces and then having a utility class that copied interface properties. What you end up with is something like this:

public interface IHaveAAndB
{
    bool A { get; set; }
    bool B { get; set; }
}

public class Foo : IHaveAAndB
{     
    public bool A { get; set; }     
    public bool B { get; set; }     
    public bool C { get; set; }     
    public bool D { get; set; }     
    public bool E { get; set; } 
}  

public class Bar : IHaveAAndB
{     
    public bool A { get; set; }     
    public bool B { get; set; } 
} 

// Disclaimer - I've not tested whether this compiles but essentially
// make the method generic and call it using the interface type
// and you can then do a copy from one set of properties to the other
// e.g. CopyInterfaceProperties<IHaveAAndB>(new Foo(), new Bar());
public static void CopyInterfaceProperties<T>(T e1, T e2)     
{         
    foreach (var prop in typeof(T).GetProperties())         
    {          
        if (prop.CanRead && prop.CanWrite)  
        {
            var value = prop.GetValue(e2, null)
            prop.SetValue(e1, value, null);   
        }
    }     
} 

Just be sure to check the property can be read and written to before calling SetValue!

In the case you cannot abstract into interfaces simply checking CanRead on source and CanWrite on the destination (also checking for existance of the property on the destination) should resolve the issue you have above.

Best regards,

Upvotes: 1

Related Questions