1

I would like to copy one object to another object, and the fields with the same names and type to be copied. Perhaps using reflections.

e.g.

object1.Name = object2.Name; object1.Age = object2.Age;

However if object2.Address is not in object1 then it would be ignored and vis-versa.

Coppermill
  • 6,676
  • 14
  • 67
  • 92
  • Reflection is the ticket. Do you have a specific question, or do you just want someone to write the code for you? – ScottS Apr 06 '10 at 19:54
  • @ScottS: Isn't that what SO is for? Free freelance programming on demand! :D – Reed Copsey Apr 06 '10 at 20:14
  • You are right, what am I like. I should have really asked if this was the best option, or what other options are available. Are there any overheads for using reflections. I have written a reflections ObjectCopier, which is running a treat :-) – Coppermill Apr 07 '10 at 09:37
  • reflection is the best choice for this problem. It is much slower than "normal" code. You'll need to measure to determine if it is too slow for your application. There are techniques that allow you to only take the reflection speed hit once, and thereafter execute at near normal speed. – ScottS Apr 08 '10 at 23:00

2 Answers2

6

I answered a similar question here. The difference is that you want the from and to to have different types and to match properties by name and by type. This is not too hard.

I haven't tested this - but give it a shot

public static class ExtensionMethods
{
    public static void CopyPropertiesTo<T, U>(this T source, U dest)
    {
        var plistsource = from prop1 in typeof(T).GetProperties() where prop1.CanRead select prop;
        var plistdest = from prop2 in typeof(U).GetProperties() where prop2.CanWrite select prop;

        foreach (PropertyInfo destprop in plistdest)
        {
            var sourceprops = plistsource.Where((p) => p.Name == destprop.Name &&
              destprop.PropertyType.IsAssignableFrom(p.GetType()));
            foreach (PropertyInfo sourceprop in sourceprops)
            { // should only be one
                destprop.SetValue(dest, sourceprop.GetValue(source, null), null);
            }
        }
    }
}

}

If you don't like the extension method, you could just rewrite this to be public static void CopyPropertiesTo(object source, object dest);

this should let you do something like this:

Foo foo = new Foo();
Bar bar = GetBar();
bar.CopyPropertiesTo<Bar, Foo>(foo);
Community
  • 1
  • 1
plinth
  • 48,267
  • 11
  • 78
  • 120
  • How about if the objects have an IEnumerable, then this is not copied. Can you think of anyway that this can be done? – Coppermill Apr 08 '10 at 15:46
  • IEnumerable is a different beast altogether, therefore it should be treated differently. – plinth Apr 08 '10 at 18:25
  • This won't work for interface hierarchy - ie. interface IA { string Alfa { get; set; } }, inteface IB : IA { string Beta { get; set; } }, class B : IB { ... } if you use IB b = new B(); and b.CopyPropertiesTo(c) only the IB properties will be copied over - see http://stackoverflow.com/questions/358835/getproperties-to-return-all-properties-for-an-interface-inheritance-hierarchy – Ondrej Svejdar Aug 23 '13 at 19:34
  • Note that this code does not compiles, there are 2 errors: first on `select prop` which should be `select prop1`, and second is `.IsAssignableFrom(p.GetType())` which does not works because `p.GetType` return the type of PropertyInfo not the field type. So p.GetType() should be `p.PropertyType` – Mohammad Zatkhahi Aug 03 '22 at 10:49
1

See this post , and put a check for the object types before

Community
  • 1
  • 1
Gregoire
  • 24,219
  • 6
  • 46
  • 73