using System.Linq.Expressions;
public static void Main()
public static Func<object, object> BuildGetter(PropertyInfo propertyInfo)
var method = propertyInfo.GetGetMethod(true);
var obj = Expression.Parameter(typeof (object), "o");
Expression<Func<object, object>> expr = Expression.Lambda<Func<object, object>>(Expression.Convert(Expression.Call(Expression.Convert(obj, method.DeclaringType), method), typeof (object)), obj);
public static Action<object, object> BuildSetter(PropertyInfo propertyInfo)
bool isValueType = propertyInfo.DeclaringType.IsValueType;
var method = propertyInfo.GetSetMethod(true);
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(isValueType ? Expression.Unbox(obj, method.DeclaringType) : Expression.Convert(obj, method.DeclaringType), method, Expression.Convert(value, method.GetParameters()[0].ParameterType)), obj, value);
Action<object, object> action = expr.Compile();
public struct LocationStruct
public class LocationClass
public static void TestSetX()
Type locationClassType = typeof (LocationClass);
PropertyInfo xProperty = locationClassType.GetProperty("X");
Action<object, object> setter = PropertyHelper.BuildSetter(xProperty);
LocationClass testLocationClass = new LocationClass();
setter(testLocationClass, 10.0);
if (testLocationClass.X == 10.0)
Console.WriteLine("Worked for the class!");
Console.WriteLine("Didn't work for the class!");
Type locationStructType = typeof (LocationStruct);
xProperty = locationStructType.GetProperty("X");
setter = PropertyHelper.BuildSetter(xProperty);
LocationStruct testLocationStruct = new LocationStruct();
object boxedStruct = testLocationStruct;
setter(boxedStruct, 10.0);
testLocationStruct = (LocationStruct)boxedStruct;
if (testLocationStruct.X == 10.0)
Console.WriteLine("Worked for the struct!");
Console.WriteLine("Didn't work for the struct!");