Thursday, August 27, 2009

The Need for Cloning an Object

I am working on a project in XAF and came into the need of cloning an object but needed to exclude certain properties.  I looked into the CloneHelper but it didn’t do what I needed.  So I wrote a simple method to handle this requirement.  A few things to know, any properties that are readonly do not need to be included in the exclusion.  Also the Oid property (is readonly) does not need to be excluded.  So to get this working, copy the code:

public static T CloneObject<T>(T sourceObj, T destObj, params string[] excludeProperties)
{
// Get the properties of the Source Object
PropertyInfo[] propCollection = sourceObj.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);

foreach (PropertyInfo pInfo in propCollection)
{
// Exclude any properties from the exclude list
if (Array.Find<string>(excludeProperties, val => val.Equals(pInfo.Name)) == null && !pInfo.IsDefined(typeof(NonCloneableAttribute), false))
{
PropertyInfo tmpProp = destObj.GetType().GetProperty(pInfo.Name);
if (tmpProp.CanWrite)
tmpProp.SetValue(destObj, pInfo.GetValue(sourceObj, null), null);
}
}

return destObj;
}


To use this method, simply create the object that will become the cloned object and pass the source like so:



public static MyClonedObject CloneLineItem(DevExpress.Xpo.Session session, MyClonedObject sourceLineItem, params string[] excludeProperties)
{
MyClonedObject clonedLineItem = new MyClonedObject(session);
return CloneObject<MyClonedObject>(sourceLineItem, clonedLineItem, excludeProperties);
}


Create a simple method like above and pass something like:



MyClonedObject clone = CloneLineItem(this.Session, this, "Parent", "Total", "Payments");


In this example the properties Payments, Total, and Parent will be ignored when cloned.  I could have also just called it without any exclusions like so:



MyClonedObject clone = CloneLineItem(this.Session, this);

If this helps you out let me know…


Updated: Added support for the NonCloneableAttribute attribute.



Happy Coding!!

 
Creative Commons License
Blogged Information and Code is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License.