我的应用程序根据设置动态加载 dll
来自数据库(文件、类和方法名称)。为了方便、加速和减少反射的使用,我想要一个缓存......
遵循以下想法:
MethodInfo.Invoke
没有什么表现性的(反射性能 - 创建委托(C# 属性) https://stackoverflow.com/questions/10820453/reflection-performance-create-delegate-properties-c)
我想翻译任何对方法的调用。我想到了这样的事情:
public static T Create<T>(Type type, string methodName) // or
public static T Create<T>(MethodInfo info) // to use like this:
var action = Create<Action<object>>(typeof(Foo), "AnySetValue");
一项要求是所有参数都可以是对象。
我正在尝试处理表达式,到目前为止我有这样的东西:
private void Sample()
{
var assembly = Assembly.GetAssembly(typeof(Foo));
Type customType = assembly.GetType("Foo");
var actionMethodInfo = customType.GetMethod("AnyMethod");
var funcMethodInfo = customType.GetMethod("AnyGetString");
var otherActionMethod = customType.GetMethod("AnySetValue");
var otherFuncMethodInfo = customType.GetMethod("OtherGetString");
var foo = Activator.CreateInstance(customType);
var actionAccessor = (Action<object>)BuildSimpleAction(actionMethodInfo);
actionAccessor(foo);
var otherAction = (Action<object, object>)BuildOtherAction(otherActionMethod);
otherAction(foo, string.Empty);
var otherFuncAccessor = (Func<object, object>)BuildFuncAccessor(funcMethodInfo);
otherFuncAccessor(foo);
var funcAccessor = (Func<object,object,object>)BuildOtherFuncAccessor(otherFuncMethodInfo);
funcAccessor(foo, string.Empty);
}
static Action<object> BuildSimpleAction(MethodInfo method)
{
var obj = Expression.Parameter(typeof(object), "o");
Expression<Action<object>> expr =
Expression.Lambda<Action<object>>(
Expression.Call(
Expression.Convert(obj, method.DeclaringType),
method), obj);
return expr.Compile();
}
static Func<object, object> BuildFuncAccessor(MethodInfo method)
{
var obj = Expression.Parameter(typeof(object), "o");
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();
}
static Func<object, object, object> BuildOtherFuncAccessor(MethodInfo method)
{
var obj = Expression.Parameter(typeof(object), "o");
var value = Expression.Parameter(typeof(object));
Expression<Func<object, object, object>> expr =
Expression.Lambda<Func<object, object, object>>(
Expression.Call(
Expression.Convert(obj, method.DeclaringType),
method,
Expression.Convert(value, method.GetParameters()[0].ParameterType)),
obj, value);
return expr.Compile();
}
static Action<object, object> BuildOtherAction(MethodInfo method)
{
var obj = Expression.Parameter(typeof(object), "o");
var value = Expression.Parameter(typeof(object));
Expression<Action<object, object>> expr =
Expression.Lambda<Action<object, object>>(
Expression.Call(
Expression.Convert(obj, method.DeclaringType),
method,
Expression.Convert(value, method.GetParameters()[0].ParameterType)),
obj,
value);
return expr.Compile();
}
public class Foo
{
public void AnyMethod() {}
public void AnySetValue(string value) {}
public string AnyGetString()
{ return string.Empty; }
public string OtherGetString(string value)
{ return string.Empty; }
}
有什么办法可以简化这段代码吗? (我相信只使用泛型创建一个方法是可能的。)当你有 3、4、5 个参数时,有像我一样的参数吗?
我在想,如果有这样的事情怎么办:
https://codereview.stackexchange.com/questions/1070/generic-advanced-delegate-createdelegate-using-expression-trees https://codereview.stackexchange.com/questions/1070/generic-advanced-delegate-createdelegate-using-expression-trees
但我会有多个参数(在动作或函数中),这个参数(第一个参数)是一个要执行的对象。
这可能吗?