T,T2>更快的施放Func键&LT途径;到Func键< T,对象&gt ;? [英] Faster way to cast a Func<T, T2> to Func<T, object>?

查看:120
本文介绍了T,T2>更快的施放Func键&LT途径;到Func键< T,对象&gt ;?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有投娱乐与下一个更快的方法; TEntity,TID> Func键< TEntity,对象>

 公共静态类StaticAccessors< TEntity> 
{
公共静态Func键< TEntity,TID> TypedGetPropertyFn<&TID GT;(的PropertyInfo PI)
{
VAR MI = pi.GetGetMethod();
回报率(Func键< TEntity,TID>)Delegate.CreateDelegate(typeof运算(Func键< TEntity,TID>),MI);
}

公共静态Func键< TEntity,对象> ValueUnTypedGetPropertyTypeFn(的PropertyInfo PI)
{
VAR MI = typeof运算(StaticAccessors< TEntity>)实现getMethod(TypedGetPropertyFn);
VAR genericMi = mi.MakeGenericMethod(pi.PropertyType);
VAR typedGetPropertyFn =(代表)genericMi.Invoke(空,新的[] {PI});

//慢:拉姆达包括反射调用
返回X => typedGetPropertyFn.Method.Invoke(X,新的对象[] {}); //我们可以更换吗?
}
}



有没有一种方法来转换 typedGetPropertyFn Func键< TEntity,对象> ,而不必像上面的例子中,返回的lambda反射代码




编辑:添加修改的方案




好感谢280Z28领导我下来我已经包含在下面的最终解决方案的正确道路。我已经离开了反射代码在那里不表示支持的平台。对于平台,做它呈现出的 26倍 27倍(13 / 0.5蜱平均)PERF的获取增加 INT 字符串属性

 公共静态Func键< TEntity,对象> ValueUnTypedGetPropertyTypeFn(的PropertyInfo PI)
{
VAR MI = typeof运算(StaticAccessors< TEntity>)实现getMethod(TypedGetPropertyFn);
VAR genericMi = mi.MakeGenericMethod(pi.PropertyType);
VAR typedGetPropertyFn =(代表)genericMi.Invoke(空,新的[] {PI});

#如果NO_EXPRESSIONS
返回X => typedGetPropertyFn.Method.Invoke(X,新的对象[] {});
的#else
VAR typedMi = typedGetPropertyFn.Method;
VAR OBJ = Expression.Parameter(typeof运算(对象),oFunc);
VAR EXPR = Expression.Lambda<&Func键LT; TEntity,对象>> (
Expression.Convert(
Expression.Call(
Expression.Convert(OBJ,typedMi.DeclaringType),
typedMi

的typeof(对象)

OBJ
);
返回expr.Compile();
#ENDIF
}


解决方案

如你所知,你可以得到一个的MethodInfo PropertyInfo.GetGetMethod()。从这一点,你可以用下面的获得<为code> Func键<对象,对象> 来检索该属性。通过类似的方法,你可以返回一个强类型的 Func键< TObject的,TResult> 。对于任何给定的MethodInfo ,您应该缓存这个调用的结果,如果你需要比一次更因为这种方法至少是一个数量级比调用产生的代表更贵

 私有静态Func键<对象,对象> BuildAccessor(MethodInfo的方法)
{
ParameterExpression OBJ = Expression.Parameter(typeof运算(对象),目标文件);

表达式来; Func键<对象,对象>> EXPR =
Expression.Lambda<&Func键LT;对象,对象>>(
Expression.Convert(
Expression.Call(
Expression.Convert(OBJ,method.DeclaringType)
法),
的typeof(对象)),
OBJ);

返回expr.Compile();
}


Is there a faster way to cast Fun<TEntity, TId> to 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?
 }
}

Is there a way to convert typedGetPropertyFn to a Func<TEntity, object> without having reflection code in the returned lambda like the example above?

EDIT: added modified solution

Ok thanks to 280Z28 for leading me down the right path which I've included in the final solution below. I've left the reflection code in there for platforms that don't support Expressions. For platforms that do it's showing a 26x to 27x (13 / .5 ticks avg) perf increase for getting int and string properties.

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
}

解决方案

As you know, you can obtain a MethodInfo from PropertyInfo.GetGetMethod(). From that, you can use the following to get a Func<object, object> to retrieve that property. By a similar method, you could return a strongly-typed Func<TObject, TResult>. For any given MethodInfo, you should cache the results of this call if you need it more than once since this method is at least an order of magnitude more expensive than calling the resulting delegate.

private static Func<object, object> BuildAccessor(MethodInfo method)
{
    ParameterExpression obj = Expression.Parameter(typeof(object), "obj");

    Expression<Func<object, object>> expr =
        Expression.Lambda<Func<object, object>>(
            Expression.Convert(
                Expression.Call(
                    Expression.Convert(obj, method.DeclaringType),
                    method),
                typeof(object)),
            obj);

    return expr.Compile();
}

这篇关于T,T2&GT;更快的施放Func键&LT途径;到Func键&LT; T,对象&gt ;?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆