c# - Can one copy the contents of one object to another dynamically if they have the same interface? -


for example, if have 2 objects, 1 of type monkey , other of type dog, , both implement ianimal, this:

interface ianimal {   int numberofeyes {get; set;}   string name {get; set;} } 

i want this:

monkey monkey = new monkey() { numberofeyes = 7, name = "henry" }; dog dog = new dog(); myfancyclass.dynamiccopy(monkey, dog, typeof(ianimal)); debug.assert(dog.numberofeyes == monkey.numberofeyes); 

i imagine 1 can create class myfancyclass using reflection... clever person have idea?

thanks, stephen

a reflection based solution follows. note reflection work done once per type , cached, overhead should minimal. work .net 3.5 , not restricted interfaces.

note use reflection properties on type t , filter properties have both getters , setters. build expression tree each property retrieves value source , assigns value target. expression trees compiled , cached in static field. when copyproperties method called, invokes copier each property, copying properties defined in type t.

// usage monkey monkey = new monkey() { numberofeyes = 7, name = "henry" }; dog dog = new dog(); dynamiccopy.copyproperties<ianimal>(monkey, dog); debug.assert(dog.numberofeyes == monkey.numberofeyes);  ...      // copier public static class dynamiccopy {     public static void copyproperties<t>(t source, t target)     {         helper<t>.copyproperties(source, target);     }      private static class helper<t>     {         private static readonly action<t, t>[] _copyprops = prepare();          private static action<t, t>[] prepare()         {             type type = typeof(t);             parameterexpression source = expression.parameter(type, "source");             parameterexpression target = expression.parameter(type, "target");              var copyprops = prop in type.getproperties(bindingflags.instance | bindingflags.public | bindingflags.nonpublic)                             prop.canread && prop.canwrite                             let getexpr = expression.property(source, prop)                             let setexpr = expression.call(target, prop.getsetmethod(true), getexpr)                             select expression.lambda<action<t, t>>(setexpr, source, target).compile();              return copyprops.toarray();         }          public static void copyproperties(t source, t target)         {             foreach (action<t, t> copyprop in _copyprops)                 copyprop(source, target);         }     } } 

Comments

Popular posts from this blog

c++ - How do I get a multi line tooltip in MFC -

asp.net - In javascript how to find the height and width -

c# - DataTable to EnumerableRowCollection -