我正在使用反射来调用方法,而使用 Invoke() 调用方法对我来说并不适用,太慢了。我生成数千 - 数百万个方法调用,它是一个测试自动化工具。在编译时,我对方法名称、参数类型或返回类型一无所知。所以 Jon Skeet 关于 using delegates to cache reflection 的文章在这里没有帮助。 这是我所拥有的:
foreach (MethodInfo method in _methods)
{
foreach (var p in method.GetParameters())
{
var paramValue = Utils.RandomizeParamValue(p.ParameterType.Name);
parameters.Add(paramValue);
}
var result = method.Invoke(_objectInstance, parameters.ToArray());
//_objectInstance is the class instance of which the method is a member of.
}
我研究了 DLR(ExpandoObject、DynamicObject),但我不确定它是否有我要找的东西。我正在寻找的是一种绕过反射开销或缓存方法调用的方法,即使结果是一个丑陋的 hack。我错过了一个常见的黑客攻击吗?我可以深入到 IL 级别并在那里做一些技巧吗?
最佳答案
一种选择是使用表达式树来构建将调用您的方法的委托(delegate)。 MSDN在Expression Trees有介绍文章,特别是你需要 MethodCallExpression
创建一个表达式示例(来自 MethodCallExpression
文章):
string[,] gradeArray =
{ {"chemistry", "history", "mathematics"}, {"78", "61", "82"} };
var arrayExpression = Expression.Constant(gradeArray);
// Create a MethodCallExpression that represents indexing
// into the two-dimensional array 'gradeArray' at (0, 2).
// Executing the expression would return "mathematics".
var methodCallExpression = Expression.ArrayIndex(
arrayExpression,
Expression.Constant(0),
Expression.Constant(2));
编译
委托(delegate)示例的表达式(来自主要文章):
Expression<Func<int, bool>> expr = num => num < 5;
Func<int, bool> result = expr.Compile();
Console.WriteLine(result(4));
关于c# - 当方法信息仅在运行时已知时优化 MethodInfo.Invoke,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20926828/