使用反射传递 func<T,bool> 作为参数?



我有一个方法:

public bool DoStuff<T>(T obj) {
// Do Stuff
return result;
}

我需要把它作为一个Func<T、 bool>在编译时我不知道的另一个方法的参数。假设这个方法看起来像:

public int Any(Func<int, bool> arg) {
}

public int Any(Func<string, bool> arg) {
}

所以我调用这样的方法:

return instance.GetType().InvokeMember(method.Name, BindingFlags.InvokeMethod, null, instance, args);

我想不出的是如何将DoStuff作为Func<T、 bool>,其中,我在编译时不知道t,但在运行时知道它,并将它填充到对象[]中,作为方法调用的参数提供。

如果有帮助的话,我正在写一个简单语言的翻译。DoStuff将用简单语言解释lambda表达式,调用的方法将是由解释器的使用者提供的.NET函数。

更新

在遵循Hans评论中提供的链接后(谢谢!(我实现了以下内容:

Type delegateType = typeof(Func<,>).MakeGenericType(new []{argType, typeof(bool)});
MethodInfo delegatedMethod = this.GetType().GetMethod(nameof(DoStuff), BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Instance);
MethodInfo generic = delegatedMethod.MakeGenericMethod(argType);
Delegate myDelegate = Delegate.CreateDelegate(delegateType, this, generic);
var args = new object[] { myDelegate };
return instance.GetType().InvokeMember(method.Name, BindingFlags.InvokeMethod, null, instance, args);

但是InvokeMember调用为我提供了System.MissingMethodException:"Method"MyDomain.Any"not found">

当我在Visual Studio中检查myDelegate变量时,它显示:

myDelegate = {Method = {Boolean DoStuff[Func`2](System.Func`2[System.Int32,System.Boolean])} 

它是args数组中唯一的元素,我调用的方法签名是:

public int Any(Func<int, bool> arg)

instance是包含Any方法的类的实例,而method则是Any方法中的MethodInfo。

所以这里有一些有效的代码:

public class AnyImplementer
{
public int Any(Func<int, bool> func)
{
return func(10)? 1: 0;
}

}
public class DoStuffer
{
public bool DoStuff<T>(T obj)
{
return obj.ToString() != string.Empty;
}
public int a(Type argType, AnyImplementer anyImplementer)
{
Type delegateType = typeof(Func<,>).MakeGenericType(new[] { argType, typeof(bool) });
MethodInfo delegatedMethod = this.GetType().GetMethod(nameof(DoStuff), BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Instance);
MethodInfo generic = delegatedMethod.MakeGenericMethod(argType);
Delegate myDelegate = Delegate.CreateDelegate(delegateType, this, generic);
var args = new object[] { myDelegate };
return (int)anyImplementer.GetType().InvokeMember("Any", BindingFlags.InvokeMethod, null, anyImplementer, args);
}
}

public class Program
{

public static void Main(string[] args)
{
DoStuffer DoStuffer = new DoStuffer();
AnyImplementer anyImplementer = new AnyImplementer();
Console.WriteLine(DoStuffer.a(typeof(int), anyImplementer));

}

}

也可访问https://pastebin.com/raw/3UxN6Sn4-其想法是(基于OP的更新和相关问题(使用从通用方法组的方法信息构建的委托来创建将方法实例包装到对象中的方法。

最新更新