public void Update_an_object_using_precompiled_accessors() { var bingo = new Bingo { X = 3, Y = 4 }; var x = CompiledAccessors.CompiledGetter(typeof(Bingo), "X")(bingo); Assert.AreEqual(3, x); CompiledAccessors.CompiledSetter(typeof(Bingo), "X")(bingo, 4); x = CompiledAccessors.CompiledGetter(typeof(Bingo), "X")(bingo); Assert.AreEqual(4, x); var smartSetter = CompiledAccessors.CompiledSmartSetter(typeof(Bingo), "Message"); Assert.IsNotNull(smartSetter); // a smart setter sets the property only if value is different var changed = smartSetter(bingo, "test"); Assert.IsTrue(changed); changed = smartSetter(bingo, "test"); Assert.IsFalse(changed); changed = smartSetter(bingo, "different"); Assert.IsTrue(changed); }
/// <summary> /// </summary> /// <param name="propertyName"></param> /// <param name="root">the root (entry point) of the object graph</param> /// <param name="parent">the owner of the property</param> /// <param name="value"></param> /// <returns></returns> public ICollection <string> SetProperty(string propertyName, object root, object parent, object value) { var modified = new HashSet <string>(); var smartSetter = CompiledAccessors.CompiledSmartSetter(parent.GetType(), propertyName); var hasChanged = smartSetter(parent, value); if (hasChanged) { modified.Add(propertyName); Cascade(propertyName, root, modified, 1); } return(modified); }
public void Precompiled_accessors_are_much_faster_then_reflexion_based_ones() { var property = typeof(Bingo).GetProperty("X"); var getter = CompiledAccessors.CompiledGetter(typeof(Bingo), "X"); var setter = CompiledAccessors.CompiledSetter(typeof(Bingo), "X"); var smartSetter = CompiledAccessors.CompiledSmartSetter(typeof(Bingo), "X"); var bingo = new Bingo { X = 3, Y = 4 }; var time0 = TimeInMilliseconds(i => { var before = (int)getter(bingo); setter(bingo, before + 1); }, 1000000); Console.WriteLine("Compiled took {0} ms", time0); var time1 = TimeInMilliseconds(i => { var before = (int)property.GetValue(bingo); property.SetValue(bingo, before + 1); }, 1000000); Console.WriteLine("Reflexion-based took {0} ms", time1); var time2 = TimeInMilliseconds(i => smartSetter(bingo, i), 1000000); Console.WriteLine("Compiled smart seter took {0} ms", time2); Assert.Less(time2 * 5, time1); // compiled smart setters should be faster Assert.Less(time0 * 5, time1); // compiled accessors should be much faster than reflexion based ones }