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
Post a Comment