如何创建函数当a's方法有参数时
本文关键字:方法 参数 何创建 创建 函数 | 更新日期: 2023-09-27 18:10:10
我试图调用一个方法,在一个函数,但使用反射。当方法无参数时,我已经让它工作了,但我不知道如何在有参数时调用它。这是一个人为的简化的例子,但它可以简化问题。直到运行时我才知道要添加的参数。
指针吗?我必须使用表达式树吗?有更简单的方法吗?
public void Main()
{
//works
CallFunction(typeof (Processor), "Count");
//I don't understand what I need to modify to make add work
CallFunction(typeof (Processor), "Add");
}
public void CallFunction(Type type, string methodToCall)
{
var targetMethod = type.GetMethod(methodToCall);
var constructedType = typeof (MethodCaller<>).MakeGenericType(type);
dynamic target = Activator.CreateInstance(constructedType);
var method = constructedType.GetMethod("Do").MakeGenericMethod(targetMethod.ReturnType);
var func = typeof (Func<,>).MakeGenericType(type, targetMethod.ReturnType);
var toCall = Delegate.CreateDelegate(func, targetMethod);
method.Invoke(target, new object[] { toCall });
}
public class Processor
{
public int Count()
{
return 1;
}
public int Add(int toAdd)
{
return 1 + toAdd;
}
}
public class MethodCaller<TParm> where TParm : new()
{
public TResult Do<TResult>(Func<TParm, TResult> func)
{
return func(new TParm());
}
}
Like type.InvokeMember(method_name, System.Reflection.BindingFlags.InvokeMethod, null, type_instance, new object[] { param1, param2, param3 });
?
https://msdn.microsoft.com/en-us/library/66btctbe (v = vs.110) . aspx
实际上整个CallFunction
方法可以这样简化:
public void CallFunction(Type type, string methodToCall, params object[] args)
{
// Why this part is so complex? Do I miss something?
//var constructedType = typeof (MethodCaller<>).MakeGenericType(type);
//dynamic target = Activator.CreateInstance(constructedType);
var target = Activator.CreateInstance(type);
var result = type.InvokeMember(method_name, System.Reflection.BindingFlags.InvokeMethod, null, target, args);
// ... do something with result if you need ...
}
如果您需要MethodCaller.Do
,但是可以牺牲签名类型(或者DoTyped
的装箱/拆箱性能)
public void CallFunction(Type type, string methodToCall, params object[] args)
{
var delegate_wrapper = new Func<object, object>(
instance => type.InvokeMember(methodToCall, BindingFlags.InvokeMethod, null, instance, args)
);
var target_method = type.GetMethod(methodToCall);
var mc_custom_type = typeof (MethodCaller<>).MakeGenericType(type);
var mc_instance = Activator.CreateInstance(mc_custom_type);
var mc_custom_method = mc_custom_type.GetMethod("Do").MakeGenericMethod(target_method.ReturnType);
mc_custom_method.Invoke(mc_instance, new object[] { delegate_wrapper });
}
public class MethodCaller<TParm> where TParm : new()
{
public TResult DoTyped<TResult>(Func<TParm, TResult> func)
{
return Do<TResult>(oinstance=>func((TParm)oinstance));
}
public TResult Do<TResult>(Func<object, object> func)
{
Console.WriteLine("I AM DO");
return (TResult)func(new TParm());
}
}
你试过看一下即兴框架吗?它主要用于鸭子类型,但库提供了相当灵活的api来访问方法和传递参数。
https://github.com/ekonbenefits/impromptu-interface/wiki/UsageReallyLateBinding