【问题标题】:How to assign a method obtained through reflection to a delegate? (or: how to speed up method calls through reflection)如何将通过反射获得的方法分配给委托? (或:如何通过反射加快方法调用)
【发布时间】:2013-10-23 11:01:20
【问题描述】:

我知道已经有这样的问题,但我真的不明白答案(而且我似乎无法评论它们)。

我对反射完全陌生,对代表也很陌生,所以这对我来说相当困难。

前段时间我用反射(第一次)得到一个方法,我是这样做的(简化):

object perlinObj;
MethodInfo PerlinMethod = null;    
//...
ConstructorInfo constructor = type.GetConstructor(Type.EmptyTypes);
perlinObj = constructor.Invoke(new object[] { });
PerlinMethod = type.GetMethod("GetValue", new Type[] { typeof(Vector3) });
//...
float PerlinFunction(Vector3 pos)
{
   return (float)((Double)PerlinMethod.Invoke(perlinObj, new object[] { pos }));
}

这可行,但问题是它比直接调用方法要慢得多。 所以我想,也许我可以以某种方式将它分配给一个委托,然后调用委托而不是使用调用,我认为这会更快。 (是吗?)

但我找不到如何做到这一点。 我不理解 msdn 上的文档:http://msdn.microsoft.com/en-us/library/ms228976.aspx(我什至不确定它们是否与我尝试做的一样), 阅读以下内容我也不明白我必须做什么:Assign method to delegate through reflection

(而且我尝试过的没有用)

那么谁能在我提供的示例代码中向我解释我必须做什么?

【问题讨论】:

    标签: c# reflection delegates unity3d invoke


    【解决方案1】:

    要以“简单”的方式执行此操作,您需要比object 更准确地了解目标;即代替:

    object perlinObj;
    

    你需要:

    SomeType perlinObj;
    

    然后,我们不存储 MethodInfo,而是使用 Delegate.CreateDelegate 来创建委托 - 请注意,为了方便起见,我在这里使用 int 代替 Vector3

    Func<SomeType, int, float> PerlinMethod;
    //...
    PerlinMethod = (Func<SomeType, int, float>) Delegate.CreateDelegate(
            typeof(Func<SomeType, int, float>),
            null,
            type.GetMethod("GetValue", new Type[] { typeof(int) }));
    //...
    float PerlinFunction(int pos)
    {
        return PerlinMethod(perlinObj, pos);
    }
    

    注意,如果目标实例永远不会改变,你可以简化:

    Func<int, float> PerlinMethod;
    //...
    PerlinMethod = (Func<int, float>) Delegate.CreateDelegate(
            typeof(Func<int, float>),
            perlinObj,
            type.GetMethod("GetValue", new Type[] { typeof(int) }));
    //...
    float PerlinFunction(int pos)
    {
        return PerlinMethod(pos);
    }
    

    如果你不能做到这一点,那么就需要使用更高级的元编程; ILGeneratorExpression:

    Func<object, int, float> PerlinMethod;
    //...
    var target = Expression.Parameter(typeof(object));
    var arg = Expression.Parameter(typeof(int));
    var call = Expression.Call(
        Expression.Convert(target, type),
        type.GetMethod("GetValue", new Type[] { typeof(int) }),
        arg);
    
    PerlinMethod = Expression.Lambda<Func<object,int,float>>(
        call, target, arg).Compile();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-09-21
      • 2010-12-10
      • 1970-01-01
      • 2012-09-22
      • 2015-11-16
      • 2011-12-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多