Property Copying With Dynamic Objects in .NET 4.0
by Joel Holder
[TestMethod]
public void Can_Set_Get_Properties()
{
dynamic expandable = new ExpandableObject();
expandable.Properties.Add(“foo”, “good stuff”);
Assert.AreEqual(expandable.foo, expandable.Properties[“foo”]);
expandable.bar = “yummy”;
Assert.AreEqual(expandable.bar, expandable.Properties[“bar”]);
}
[TestMethod()]
public void Expandable_Object_Can_Copy_Properties_From_To()
{
dynamic expandable = new ExpandableObject();
var testObj = new TestObject
{
ID = 1,
Description = “ASDFASDF”,
Name = “GGGG”,
UnitPrice = 6
};
</p>
</span></font></span> expandable.CopyPropertiesFrom(testObj, null);
Assert.AreEqual(expandable.Description, testObj.Description); var testObj2 = new TestObject();
expandable.CopyPropertiesTo(testObj2, null); Assert.AreEqual(testObj, testObj2);
} Here is the implementation of ExpandableObject. </p>
public class ExpandableObject : DynamicObject { Dictionary<string, object> _properties = new Dictionary<string, object>(); public Dictionary<string, object> Properties { get { return _properties; } set { _properties = value; } } public override bool TrySetMember(SetMemberBinder binder, object value) { _properties[binder.Name] = value; return true; } public override bool TryGetMember(GetMemberBinder binder, out object result) { return _properties.TryGetValue(binder.Name, out result); } public void CopyPropertiesFrom(object source, List<string> ignoreList) { ignoreList = ignoreList ?? new List<string>(); </font></span> foreach (var property in source.GetType().GetProperties().Where(p => p.CanRead)) { var key = property.Name; if (!ignoreList.Contains(key)) { var value = property.GetValue(source, null); this.Properties[key] = value; } } } public void CopyPropertiesTo(object destination, List<string> ignoreList) { ignoreList = ignoreList ?? new List<string>(); var destProps = destination.GetType().GetProperties().ToList(); this.Properties.Keys.ToList().ForEach(key => {
if (!ignoreList.Contains(key)) { var value = this.Properties[key]; var property = destProps.Where(p => p.CanWrite && p.Name == key && p.PropertyType == value.GetType()).FirstOrDefault(); if (property != null) { property.SetValue(destination, value, null); } } }); } }
There is no spoon… Enjoy…