我需要创建一个方法来动态检查作为参数传递的方法委托(delegate)。但我无法强制表达式树接受任何方法,无论其签名如何。
这是我的方法(无法编译:错误 CS0030:无法将类型“method”转换为“Delegate”
)
public void Examine<T>(Expression<Func<T, Delegate>> expression2)
{
// examine expression tree to get method name (MethodInfo)
}
我想这样调用它:
Examine<Foo>(x => foo1.Test1);
Examine<Bar>(x => bar2.DifferentMethod2);
// etc, with other methods
地点:
- 类 Foo 有方法:
bool Test1(int num)
- 类 Bar 有方法:'string DifferentMethod2(string a, string b)`
- 还有许多其他
如何实现?
备注:
- 我不能使用 Func<> 或 Action<>,因为有许多可能的方法签名需要通过我不会引用的参数类型来接受。
最佳答案
您确实必须使用 Func
或 Action
,但是您可以在调用方而不是方法方使用它,这样您仍然可以接受任何类型。
static void Main()
{
Foo foo1 = null;
Bar bar2 = null;
Examine<Foo>(x => (Func<int,bool>)foo1.Test1);
Examine<Bar>(x => (Func<string,string,string>)bar2.DifferentMethod2);
}
public static void Examine<T>(Expression<Func<T, Delegate>> expression2)
{
// examine expression tree to get method name (MethodInfo)
}
这将创建一个类似于
的表达式.Lambda #Lambda1<System.Func`2[SandboxConsole.Foo,System.Delegate]>(SandboxConsole.Foo $x) {
(System.Func`2[System.Int32,System.Boolean]).Call .Constant<System.Reflection.MethodInfo>(Boolean Test1(Int32)).CreateDelegate(
.Constant<System.Type>(System.Func`2[System.Int32,System.Boolean]),
.Constant<SandboxConsole.Program+<>c__DisplayClass0_0>(SandboxConsole.Program+<>c__DisplayClass0_0).foo1)
}
和
.Lambda #Lambda1<System.Func`2[SandboxConsole.Bar,System.Delegate]>(SandboxConsole.Bar $x) {
(System.Func`3[System.String,System.String,System.String]).Call .Constant<System.Reflection.MethodInfo>(System.String DifferentMethod2(System.String, System.String)).CreateDelegate(
.Constant<System.Type>(System.Func`3[System.String,System.String,System.String]),
.Constant<SandboxConsole.Program+<>c__DisplayClass0_0>(SandboxConsole.Program+<>c__DisplayClass0_0).bar2)
}
对于两次调用。
关于c# - ExpressionTree 作为方法参数接受任何方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39280206/