Given 2 objects A and B of type T, I want to assign the properties' values in A to the same properties in B without doing an explicit assignment for each property.
I want to save code like this:
b.Nombre = a.Nombre; b.Descripcion = a.Descripcion; b.Imagen = a.Imagen; b.Activo = a.Activo;
doing something like
a.ApplyProperties(b);
Is it possible?
In general, when we try to copy one object to another object, both the objects will share the same memory address. Normally, we use assignment operator, = , to copy the reference, not the object except when there is value type field.
The Object.assign() method copies all enumerable own properties from one or more source objects to a target object. It returns the modified target object.
Because I believe Jon's version is a tad too complicated and and Steve's version is too simple, and I like Daniel's idea of an extension class.
Plus a Generic version is pretty but unnecessary as all items are objects.
I would like to volunteer my lean and mean version. Credits to all the above. :D
Code:
using System; using System.Reflection; /// <summary> /// A static class for reflection type functions /// </summary> public static class Reflection { /// <summary> /// Extension for 'Object' that copies the properties to a destination object. /// </summary> /// <param name="source">The source.</param> /// <param name="destination">The destination.</param> public static void CopyProperties(this object source, object destination) { // If any this null throw an exception if (source == null || destination == null) throw new Exception("Source or/and Destination Objects are null"); // Getting the Types of the objects Type typeDest = destination.GetType(); Type typeSrc = source.GetType(); // Iterate the Properties of the source instance and // populate them from their desination counterparts PropertyInfo[] srcProps = typeSrc.GetProperties(); foreach (PropertyInfo srcProp in srcProps) { if (!srcProp.CanRead) { continue; } PropertyInfo targetProperty = typeDest.GetProperty(srcProp.Name); if (targetProperty == null) { continue; } if (!targetProperty.CanWrite) { continue; } if (targetProperty.GetSetMethod(true) != null && targetProperty.GetSetMethod(true).IsPrivate) { continue; } if ((targetProperty.GetSetMethod().Attributes & MethodAttributes.Static) != 0) { continue; } if (!targetProperty.PropertyType.IsAssignableFrom(srcProp.PropertyType)) { continue; } // Passed all tests, lets set the value targetProperty.SetValue(destination, srcProp.GetValue(source, null), null); } } }
Usage:
/// <summary> /// ExampleCopyObject /// </summary> /// <returns></returns> public object ExampleCopyObject() { object destObject = new object(); this.CopyProperties(destObject); // inside a class you want to copy from Reflection.CopyProperties(this, destObject); // Same as above but directly calling the function TestClass srcClass = new TestClass(); TestStruct destStruct = new TestStruct(); srcClass.CopyProperties(destStruct); // using the extension directly on a object Reflection.CopyProperties(srcClass, destObject); // Same as above but directly calling the function //so on and so forth.... your imagination is the limits :D return srcClass; } public class TestClass { public string Blah { get; set; } } public struct TestStruct { public string Blah { get; set; } }
As I was bored and a linq version was suggested by a comment
using System; using System.Linq; using System.Reflection; /// <summary> /// A static class for reflection type functions /// </summary> public static class Reflection { /// <summary> /// Extension for 'Object' that copies the properties to a destination object. /// </summary> /// <param name="source">The source.</param> /// <param name="destination">The destination.</param> public static void CopyProperties(this object source, object destination) { // If any this null throw an exception if (source == null || destination == null) throw new Exception("Source or/and Destination Objects are null"); // Getting the Types of the objects Type typeDest = destination.GetType(); Type typeSrc = source.GetType(); // Collect all the valid properties to map var results = from srcProp in typeSrc.GetProperties() let targetProperty = typeDest.GetProperty(srcProp.Name) where srcProp.CanRead && targetProperty != null && (targetProperty.GetSetMethod(true) != null && !targetProperty.GetSetMethod(true).IsPrivate) && (targetProperty.GetSetMethod().Attributes & MethodAttributes.Static) == 0 && targetProperty.PropertyType.IsAssignableFrom(srcProp.PropertyType) select new { sourceProperty = srcProp, targetProperty = targetProperty }; //map the properties foreach (var props in results) { props.targetProperty.SetValue(destination, props.sourceProperty.GetValue(source, null), null); } } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With