我要做的是以下(我必须不知道它是否可能);我知道运行时类型。我知道我想在运行时调用哪种方法。但是,我在编译时不知道这一点。
GetFunction方法无法创建给定methodInfo的委托,因为inparam不是object类型。
有没有办法创建一个函数的委托,我只知道我想委派的方法的Type和MethodInfo?
public sealed class Functions {
public static int SetStrValue(string s) {
// set a string
}
public static int SetIntValue(int i) {
// set an int
}
}
public sealed class GetFunctions {
public Func<object, int> GetFunction(Type type, MethodInfo methodInfo) {
// what I would like to do.
Func<object, int> func = Delegate.CreateDelegate(typeof(Func<object, int>), methodInfo);
return t => func(t);
}
}
public class InvokeFunctions {
public void invokeFunction() {
Type t = typeof(String);
MethodInfo methodInfo = typeof(Functions).GetMethod("SetStrValue");
int i = GetFunctions.GetFunction(t, methodInfo).Invoke("hello");
}
}
答案 0 :(得分:3)
您可以使用表达式树来创建委托。由于编译时类型未知,您可以尝试在运行时将参数强制转换为适当的类型。
public sealed class GetFunctions
{
public static Func<object, int> GetFunction(MethodInfo methodInfo)
{
var obj = Expression.Parameter(typeof (object), "obj");
var convert = Expression.Convert(obj, methodInfo.GetParameters().First().ParameterType);
var call = Expression.Call(methodInfo, convert);
var lambda = Expression.Lambda<Func<object, int>>(call, obj);
return lambda.Compile();
}
}
public class InvokeFunctions
{
public void invokeFunction()
{
MethodInfo methodInfo = typeof(Functions).GetMethod("SetStrValue");
int i = GetFunctions.GetFunction(methodInfo).Invoke("hello");
MethodInfo methodInfo2 = typeof(Functions).GetMethod("SetIntValue");
int i2 = GetFunctions.GetFunction(methodInfo2).Invoke(1);
}
}
我删除了Type
参数并直接从Method的第一个参数中获取,如果这不是预期的行为,则可以更改它。
答案 1 :(得分:0)
您可以使用泛型将其简化为:
public sealed class Functions
{
public static int SetValue<T>(T input)
{
// set a value of type T
}
}
用以下方法调用该函数:
Functions.SetValue<string>("hello");
如果您仍想使用委托,则可以使用通用委托定义:
public delegate int MyDelegateFunction<T>(T input);