Wednesday, April 14, 2010

Generic Property Merge Using Reflection

I have found this generic merge method to be very useful. Before you cut and paste it into you Silverlight application, let me explain why I created it.

  1. public virtual bool MergeValues(object oSource, bool bNotifyUI)
  2. {
  3. bool bSucess = true;
  4. foreach (var oPropInfo in oSource.GetType().GetProperties())
  5. {
  6. if (!oPropInfo.CanRead !oPropInfo.CanWrite oPropInfo.Name == "Item")
  7. continue;
  8. var oResult = oPropInfo.GetValue(oSource, null);
  9. if (oResult != oPropInfo.GetValue(this, null))
  10. try
  11. {
  12. oPropInfo.SetValue(this, oResult, null);
  13. if (bNotifyUI)
  14. NotifyOfPropertyChange(oPropInfo.Name);
  15. }
  16. catch
  17. {
  18. bSucess = false;
  19. }
  20. }
  21. return bSucess;
  22. }

Once Silverlight binds a property to a XAML element, your program will perform a lot better if you just change the value rather then rebind to a new object. I have not done any detailed timing tests, but by using this code in a before / after way you can “feel” that this is faster.

I know there is a performance cost when you access a property via reflection, but I am willing to pay that cost to have a solution that is VERY reliable.

By defining this method as virtual you are able to override to build a version that performs better, for example:

  1. public override bool MergeValues(object oSource, bool bNotifyUI)
  2. {
  3. bool bSucess = true;
  4. Person oPerson = oSource as Person;
  5. this.ID = oPerson.ID;
  6. this.FirstName = oPerson.FirstName;
  7. this.MiddleName = oPerson.MiddleName;
  8. this.LastName = oPerson.LastName;
  9. this.MostRecentFlight = oPerson.MostRecentFlight;
  10. return bSucess;
  11. }

But this solution is not as reliable and requires me to change the code every time I modify the properties in this class.

Feel free to cut, paste and modify this code to meet your own coding objectives.