我的应用程序根据数据库中的设置(文件、类和方法名称)动态加载 dll。为了方便、加快和减少反射的使用,我想有一个缓存....
遵循使用的想法:
MethodInfo.Invoke
没有什么表演(反射性能 - 创建委托(属性 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 时,像我一样有任何参数吗?
我在想,如果有这样的事情怎么办:
但我将有多个参数(在动作或函数中),这个参数(第一个参数)是一个要执行的对象。这可能吗?