Property Reflection
Two static utilities.
- Copy: Copy all properties from one object to another (even if a different type). Useful for downcasting.
- AreEqual: Check whether all property values are the same. Useful for duplicate checking.
Use
var p = new Person { Id = 1, DoB = DateTime.Now, Name = "Bob" };
var p2 = p;
var p3 = new Person { Id = 2, DoB = DateTime.Now, Name = "Jane" };
Assert.IsTrue(p.Equals(p2));
Assert.IsTrue(PropertyReader.AreEqual(p, p2), "Reference equals");
Assert.IsFalse(PropertyReader.AreEqual(p, p3), "Different properties");
PropertyReader.Copy(p, p3); //copy all properties from p to p3
Assert.IsFalse(p.Equals(p3), "Different objects");
Assert.IsTrue(PropertyReader.AreEqual(p, p3), "Same properties");
Class
using System.Diagnostics;
using System.Reflection;
namespace Library.Data
{
/// <summary>
/// Utilities to read properties with reflection
/// </summary>
public static class PropertyReader
{
/// <summary>
/// Copies all properties from one object to properties with the same name on another object (which need not be the same type).
/// </summary>
/// <remarks>
/// This is a shallow copy. This can be useful for downcasting from one object to a more derived one.
/// </remarks>
public static void Copy(object from, object to)
{
if (from == null || to == null) return;
//get all properties from "from"
PropertyInfo[] allProps = from.GetType().GetProperties();
PropertyInfo toProp;
foreach (PropertyInfo fromProp in allProps)
{
//find property on "to" with same name
toProp = to.GetType().GetProperty(fromProp.Name);
if (toProp == null) continue; //not here
if (!toProp.CanWrite) continue; //only if writeable
//set the property value from "from" to "to"
Debug.WriteLine(toProp.Name + " = from." + fromProp.Name + ";");
toProp.SetValue(to, fromProp.GetValue(from, null), null);
}
}
/// <summary>
/// Tests whether property values of two objects are the same. This is not the same as Reference Equality (object.Equals). Useful for testing duplicate objects.
/// </summary>
public static bool AreEqual<T>(T x, T y)
{
if (x.Equals(y)) return true; //reference equality
//check nulls
if (x == null)
return y == null ? true : false;
if (y == null) return false;
//get all properties
PropertyInfo[] allProps = x.GetType().GetProperties();
foreach (PropertyInfo xProp in allProps)
{
object xValue = xProp.GetValue(x, null);
//use the same PropertyInfo with the other object
object yValue = xProp.GetValue(y, null);
//now compare their equals
if (xValue == null)
{
if (yValue == null) continue;
return false;
}
if (!xValue.Equals(yValue))
return false;
}
return true;
}
}
}