public DynamicPropertyAccessor(PropertyInfo propertyInfo) { // target: (object)((({TargetType})instance).{Property}) // preparing parameter, object type ParameterExpression instance = Expression.Parameter( typeof(object), "instance"); // ({TargetType})instance Expression instanceCast = Expression.Convert( instance, propertyInfo.ReflectedType); // (({TargetType})instance).{Property} Expression propertyAccess = Expression.Property( instanceCast, propertyInfo); // (object)((({TargetType})instance).{Property}) UnaryExpression castPropertyValue = Expression.Convert( propertyAccess, typeof(object)); // Lambda expression Expression<Func<object, object>> lambda = Expression.Lambda<Func<object, object>>( castPropertyValue, instance); this.m_getter = lambda.Compile(); MethodInfo setMethod = propertyInfo.GetSetMethod(); if (setMethod != null) { this.m_dynamicSetter = new DynamicMethodExecutor(setMethod); } }
private void Watch() { int times = 1000000; Program program = new Program(); object[] parameters = new object[] { new object(), new object(), new object() }; program.Call(null, null, null); // force JIT-compile MethodInfo methodInfo = typeof(Program).GetMethod("Call"); Stopwatch watch1 = new Stopwatch(); watch1.Start(); for (int i = 0; i < times; i++) { program.Call(parameters[0], parameters[1], parameters[2]); } watch1.Stop(); Console.WriteLine(watch1.Elapsed + " (Directly invoke)"); Stopwatch watch2 = new Stopwatch(); watch2.Start(); for (int i = 0; i < times; i++) { methodInfo.Invoke(program, parameters); } watch2.Stop(); Console.WriteLine(watch2.Elapsed + " (Reflection invoke)"); DynamicMethodExecutor executor = new DynamicMethodExecutor(methodInfo); Stopwatch watch3 = new Stopwatch(); watch3.Start(); for (int i = 0; i < times; i++) { executor.Execute(program, parameters); } watch3.Stop(); Console.WriteLine(watch3.Elapsed + " (Dynamic executor)"); }