Reflection Performance - Create Delegate (Properties C#)

This should work for you:

static Action<object, object> BuildSetAccessor(MethodInfo method)
{
    var obj = Expression.Parameter(typeof(object), "o");
    var value = Expression.Parameter(typeof(object));

    Expression<Action<object, object>> expr =
        Expression.Lambda<Action<object, object>>(
            Expression.Call(
                Expression.Convert(obj, method.DeclaringType),
                method,
                Expression.Convert(value, method.GetParameters()[0].ParameterType)),
            obj,
            value);

    return expr.Compile();
}

Usage:

var accessor = BuildSetAccessor(typeof(TestClass).GetProperty("MyProperty").GetSetMethod());
var instance = new TestClass();
accessor(instance, "foo");
Console.WriteLine(instance.MyProperty);

With TestClass:

public class TestClass 
{
    public string MyProperty { get; set; }
}

Prints out:

foo


I think you'd be better off with CreateDelegate construct if performance is the key. Since you know the signature of the method beforehand, which here is just GetGetMethod and GetSetMethod of the PropertyInfo, you can create a delegate to execute the very method with the same signature directly. Expressions would be better suited if you need to build some logic (for which you did not have a method handle) to delegates. I did some benchmarking on different routes to this problem:

Func<S, T> Getter;
Action<S, T> Setter;
PropertyInfo Property;
public void Initialize(Expression<Func<S, T>> propertySelector)
{
    var body = propertySelector.Body as MemberExpression;
    if (body == null)
        throw new MissingMemberException("something went wrong");

    Property = body.Member as PropertyInfo;



    //approaches:

    //Getter = s => (T)Property.GetValue(s, null);

    //Getter = memberSelector.Compile();

    //ParameterExpression inst = Expression.Parameter(typeof(S));
    //Getter = Expression.Lambda<Func<S, T>>(Expression.Property(inst, Property), inst).Compile();

    //var inst = Expression.Parameter(typeof(S));
    //Getter = Expression.Lambda<Func<S, T>>(Expression.Call(inst, Property.GetGetMethod()), inst).Compile();

    //Getter = (Func<S, T>)Delegate.CreateDelegate(typeof(Func<S, T>), Property.GetGetMethod());



    //Setter = (s, t) => Property.SetValue(s, t, null);

    //var val = Expression.Parameter(typeof(T));
    //var inst = Expression.Parameter(typeof(S));
    //Setter = Expression.Lambda<Action<S, T>>(Expression.Call(inst, Property.GetSetMethod(), val),
    //                                         inst, val).Compile();

    //Setter = (Action<S, T>)Delegate.CreateDelegate(typeof(Action<S, T>), Property.GetSetMethod());
}


//Actual calls (tested under loop):
public T Get(S instance)
{
    //direct invocation:
    //return (T)Property.GetValue(instance, null);

   //calling the delegate:
   //return Getter(instance);
}
public void Set(S instance, T value)
{
    //direct invocation:
    //Property.SetValue(instance, value, null);

   //calling the delegate:
   //Setter(instance, value);
}

Results for about 10000000 calls - (Get, Set):

GetValue-SetValue (direct): 3800 ms, 5500 ms

GetValue-SetValue (delegate): 3600 ms, 5300 ms

compiled expressions:

   Get: Expression.Property: 280 ms

        Expression.Call: 280 ms

        direct compile: 280 ms
   Set: 300 ms

create delegate: 130 ms, 135 ms

direct property call: 70 ms, 70 ms

I would, in your case, write:

public static Func<S, T> BuildGetAccessor<S, T>(Expression<Func<S, T>> propertySelector)
{
    return propertySelector.GetPropertyInfo().GetGetMethod().CreateDelegate<Func<S, T>>();
}

public static Action<S, T> BuildSetAccessor<S, T>(Expression<Func<S, T>> propertySelector)
{
    return propertySelector.GetPropertyInfo().GetSetMethod().CreateDelegate<Action<S, T>>();
}

// a generic extension for CreateDelegate
public static T CreateDelegate<T>(this MethodInfo method) where T : class
{
    return Delegate.CreateDelegate(typeof(T), method) as T;
}

public static PropertyInfo GetPropertyInfo<S, T>(this Expression<Func<S, T>> propertySelector)
{
    var body = propertySelector.Body as MemberExpression;
    if (body == null)
        throw new MissingMemberException("something went wrong");

    return body.Member as PropertyInfo;
}

So now you call:

TestClass cwp = new TestClass();
var access = BuildGetAccessor((TestClass t) => t.AnyValue);
var result = access(cwp);

Isn't that simpler?? Had written a generic class here to handle the exact thing.