3

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

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

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

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(我什至不确定它们是否与我尝试做的一样),从阅读本文中我也不明白我必须做什么:通过反射将方法分配给委托

(我试过的没有用)

那么任何人都可以在我提供的示例代码中向我解释我必须做什么吗?

4

1 回答 1

3

要以“简单”的方式执行此操作,您需要比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);
}

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

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();
于 2013-10-23T11:14:08.693 回答