繁体   English   中英

传递一个函数<T,bool>作为使用反射的参数?

[英]Pass a Func<T,bool> as a parameter using reflection?

我有一个方法:

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 函数。

更新

按照汉斯评论中提供的链接(谢谢!)后,我实现了以下内容:

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 的更新和相关问题)使用从泛型方法的方法信息构造的委托来创建将方法实例包装到一个对象中团体。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM