using System; using System.Collections.Generic; using System.Threading; using System.Collections; using System.Linq; using System.Text; using System.Reflection; using System.Reflection.Emit; using System.Diagnostics; using System.Linq.Expressions; namespace Test { public class Bar { } public interface IFoo { Bar Bar { get; set; } } public class Foo1 : IFoo { public Bar Bar { get; set; } } public class Foo2 : IFoo { public Bar Bar { get; set; } } public class Foo3 : IFoo { public Bar Bar { get; set; } } public delegate Bar GetPropertyValue(); public delegate void SetPropertyValue(Bar bar); public class Program { public static GetPropertyValue CreateGetPropertyValueDelegate(IFoo foo) { return (GetPropertyValue)Delegate.CreateDelegate(typeof(GetPropertyValue), foo, typeof(IFoo).GetProperty("Bar").GetGetMethod()); } public static SetPropertyValue CreateSetPropertyValueDelegate(IFoo foo) { return (SetPropertyValue)Delegate.CreateDelegate(typeof(SetPropertyValue), foo, typeof(IFoo).GetProperty("Bar").GetSetMethod()); } public static Func<IFoo, Bar> CreateGetPropertyValueFunc() { var property = typeof(IFoo).GetProperty("Bar"); var target = Expression.Parameter(typeof(IFoo)); var getPropertyValue = Expression.Property(target, property); return Expression.Lambda<Func<IFoo, Bar>>(getPropertyValue, target).Compile(); } public static Action<IFoo, Bar> CreateSetPropertyValueAction() { var property = typeof(IFoo).GetProperty("Bar"); var target = Expression.Parameter(typeof(IFoo)); var propertyValue = Expression.Parameter(typeof(Bar)); var setPropertyValue = Expression.Call(target, property.GetSetMethod(), propertyValue); return Expression.Lambda<Action<IFoo, Bar>>(setPropertyValue, target, propertyValue).Compile(); } public static void TestSetPropertyValue(int times) { var foo1 = new Foo1(); var foo2 = new Foo2(); var foo3 = new Foo3(); var bar = new Bar(); var property = typeof(IFoo).GetProperty("Bar"); var setAction = CreateSetPropertyValueAction(); var setDelegate1 = CreateSetPropertyValueDelegate(foo1); var setDelegate2 = CreateSetPropertyValueDelegate(foo2); var setDelegate3 = CreateSetPropertyValueDelegate(foo3); var stopwatch = new Stopwatch(); stopwatch.Start(); for (int i = 0; i < times; i++) { property.SetValue(foo1, bar, null); property.SetValue(foo2, bar, null); property.SetValue(foo3, bar, null); } var duration1 = stopwatch.ElapsedMilliseconds; stopwatch.Restart(); for (int i = 0; i < times; i++) { setAction(foo1, bar); setAction(foo2, bar); setAction(foo3, bar); } var duration2 = stopwatch.ElapsedMilliseconds; stopwatch.Restart(); for (int i = 0; i < times; i++) { setDelegate1(bar); setDelegate2(bar); setDelegate3(bar); } var duration3 = stopwatch.ElapsedMilliseconds; Console.WriteLine("{0, -15}{1,-15}{2,-15}{3,-15}", times, duration1, duration2, duration3); } public static void TestGetPropertyValue(int times) { var foo1 = new Foo1 { Bar = new Bar() }; var foo2 = new Foo2 { Bar = new Bar() }; var foo3 = new Foo3 { Bar = new Bar() }; var property = typeof(IFoo).GetProperty("Bar"); var getFunc = CreateGetPropertyValueFunc(); var getDelegate1 = CreateGetPropertyValueDelegate(foo1); var getDelegate2 = CreateGetPropertyValueDelegate(foo2); var getDelegate3 = CreateGetPropertyValueDelegate(foo3); var stopwatch = new Stopwatch(); stopwatch.Start(); for (int i = 0; i < times; i++) { var bar1 = property.GetValue(foo1, null); var bar2 = property.GetValue(foo2, null); var bar3 = property.GetValue(foo3, null); } var duration1 = stopwatch.ElapsedMilliseconds; stopwatch.Restart(); for (int i = 0; i < times; i++) { var bar1 = getFunc(foo1); var bar2 = getFunc(foo2); var bar3 = getFunc(foo3); } var duration2 = stopwatch.ElapsedMilliseconds; stopwatch.Restart(); for (int i = 0; i < times; i++) { var bar1 = getDelegate1(); var bar2 = getDelegate2(); var bar3 = getDelegate3(); } var duration3 = stopwatch.ElapsedMilliseconds; Console.WriteLine("{0, -15}{1,-15}{2,-15}{3,-15}", times, duration1, duration2, duration3); } static void Main() { Console.WriteLine("{0, -15}{1,-15}{2,-15}{3,-15}", "Times", "Reflection", "Expression", "Delegate"); TestSetPropertyValue(10000); TestSetPropertyValue(100000); TestSetPropertyValue(1000000); Console.WriteLine(); TestGetPropertyValue(10000); TestGetPropertyValue(100000); TestGetPropertyValue(1000000); Console.ReadLine(); } } }
1.属性set的委托
public static Action<IFoo, Bar> CreateSetPropertyValueAction() { var property = typeof(IFoo).GetProperty("Bar"); //Bar的反射的property var target = Expression.Parameter(typeof(IFoo)); //大概是与属性相对应的数据成员 var propertyValue = Expression.Parameter(typeof(Bar)); //value的类型 var setPropertyValue = Expression.Call(target, property.GetSetMethod(), propertyValue); return Expression.Lambda<Action<IFoo, Bar>>(setPropertyValue, target, propertyValue).Compile(); }
Fun<int,bool> 是一个委托
Expression<Fun<int,bool>> Expression<TDelegate> 以表达式目录树的形式将强类型 lambda 表达式表示为数据结构
下面的代码示例演示如何将 lambda 表达式表示为委托形式的可执行代码和表达式目录树形式的数据。
// Lambda expression as executable code. Func<int, bool> deleg = i => i < 5; // Invoke the delegate and display the output. outputBlock.Text += String.Format("deleg(4) = {0}", deleg(4)) + "\n"; // Lambda expression as data in the form of an expression tree. System.Linq.Expressions.Expression<Func<int, bool>> expr = i => i < 5; // Compile the expression tree into executable code. Func<int, bool> deleg2 = expr.Compile(); // Invoke the method and print the output. outputBlock.Text += String.Format("deleg2(4) = {0}", deleg2(4)) + "\n"; /* This code produces the following output: deleg(4) = True deleg2(4) = True */
http://msdn.microsoft.com/zh-SG/library/bb335710(v=vs.95).aspx
http://msdn.microsoft.com/zh-SG/library/bb355170(v=vs.90).aspx
http://kb.cnblogs.com/page/95487/
http://www.cnblogs.com/errorif/archive/2012/03/19/2406446.html