mercredi 14 janvier 2015

Get accessors from PropertyInfo as Func

I need to call properties that are determined at runtime through reflection and they are called at a high frequency. So I am looking for solution with optimal performance, which mean I'd probably avoid reflection. I was thinking of storing the property accessors as Func and Action delegates in a list and then call those.


The question now is, how do I get the accessor delagates as Func and Action delgates for later invokation?


A naïve implementation that still uses reflection for the invocation would look like this:



private Func<object> GetGetter(PropertyInfo info)
{
// 'this' is the owner of the property
return () => info.GetValue(this);
}

private Action<object> GetSetter(PropertyInfo info)
{
// 'this' is the owner of the property
return v => info.SetValue(this, v);
}


How could I implement the above methods without refelections. Would expressions be the fastest way? I have tried using expression like this:



private Func<object> GetGetter(PropertyInfo info)
{
// 'this' is the owner of the property
return
Expression.Lambda<Func<object>>(
Expression.Convert(Expression.Call(Expression.Constant(this), info.GetGetMethod()), typeof(object)))
.Compile();
}

private Action<object> GetSetter(PropertyInfo info)
{
// 'this' is the owner of the property
var method = info.GetSetMethod();
var parameterType = method.GetParameters().First().ParameterType;
var parameter = Expression.Parameter(parameterType, "value");
var methodCall = Expression.Call(Expression.Constant(this), method, parameter);

// ArgumentException: ParameterExpression of type 'System.Boolean' cannot be used for delegate parameter of type 'System.Object'
return Expression.Lambda<Action<object>>(methodCall, parameter).Compile();
}


But here the last line of GetSetter I get the following excpetion if the type of the property is not exactly of type System.Object:



ArgumentException: ParameterExpression of type 'System.Boolean' cannot be used for delegate parameter of type 'System.Object'







Aucun commentaire:

Enregistrer un commentaire