如何将通过反射获得的方法分配给委托?(或者:如何通过反射加快方法调用)
本文关键字:方法 反射 或者 何通过 调用 分配 | 更新日期: 2023-09-27 18:36:36
我知道已经有这样的问题,但我真的只是不明白答案(我似乎无法评论它们)。
我对反思是完全陌生的,对代表们来说也是相当陌生的,所以这对我来说是相当困难的。
不久前,我使用反射(第一次)来获得一种方法,我是这样做的(简化):
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 }));
}
这有效,但问题是它比直接调用方法要慢得多。所以我想,也许我可以以某种方式将其分配给委托,然后调用委托而不是使用 invoke,我认为这会更快。(是的,对吧?
但是我找不到如何做到这一点。我不明白 msdn 上的文档:http://msdn.microsoft.com/en-us/library/ms228976.aspx(我什至不确定他们是否和我试图做的一样),我也不明白我必须从阅读本文中确切地做什么:通过反射分配方法进行委派。
(我尝试的没有奏效)
那么谁能向我解释我在提供的示例代码中必须做什么?
要以"简单"的方式做到这一点,你需要比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();