![](/img/trans.png)
[英]How to pass Expression<Func<T, bool>> predicate as a parameter to a method?
[英]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.