有没有更快的方法将 Fun<TEntity, TId>
强制转换为 Func<TEntity, object>
?
public static class StaticAccessors<TEntity>
{
public static Func<TEntity, TId> TypedGetPropertyFn<TId>(PropertyInfo pi)
{
var mi = pi.GetGetMethod();
return (Func<TEntity, TId>)Delegate.CreateDelegate(typeof(Func<TEntity, TId>), mi);
}
public static Func<TEntity, object> ValueUnTypedGetPropertyTypeFn(PropertyInfo pi)
{
var mi = typeof(StaticAccessors<TEntity>).GetMethod("TypedGetPropertyFn");
var genericMi = mi.MakeGenericMethod(pi.PropertyType);
var typedGetPropertyFn = (Delegate)genericMi.Invoke(null, new[] { pi });
//slow: lambda includes a reflection call
return x => typedGetPropertyFn.Method.Invoke(x, new object[] { }); //can we replace this?
}
}
有没有一种方法可以将typedGetPropertyFn
转换为Func<TEntity, object>
,而不需要在返回的lambda中添加反射代码(就像上面的示例一样)?编辑:添加修改后的解决方案。好的,感谢280Z28给我指路,我将其包含在下面的最终解决方案中。我已经将反射代码保留在那里,以供不支持表达式的平台使用。对于支持表达式的平台,获取int
和string
属性的性能提高了26x到27x(13 / .5 ticks avg)。public static Func<TEntity, object> ValueUnTypedGetPropertyTypeFn(PropertyInfo pi)
{
var mi = typeof(StaticAccessors<TEntity>).GetMethod("TypedGetPropertyFn");
var genericMi = mi.MakeGenericMethod(pi.PropertyType);
var typedGetPropertyFn = (Delegate)genericMi.Invoke(null, new[] { pi });
#if NO_EXPRESSIONS
return x => typedGetPropertyFn.Method.Invoke(x, new object[] { });
#else
var typedMi = typedGetPropertyFn.Method;
var obj = Expression.Parameter(typeof(object), "oFunc");
var expr = Expression.Lambda<Func<TEntity, object>> (
Expression.Convert(
Expression.Call(
Expression.Convert(obj, typedMi.DeclaringType),
typedMi
),
typeof(object)
),
obj
);
return expr.Compile();
#endif
}
Bar
的编译时类型。 - mythz