我们说我的方法有以下签名:
public string Foo(Expression expression)
{
...
}
是否可以直接调用此方法,而不使用代理方法,如果是,如何?
作为一个额外的问题(要理解我为什么要这样做),是否可以声明一个方法(没有重载),在所有这些情况下都会调用它:
Foo(P p => "");
Foo((P p, Q q) => "");
Foo((P p, Q q, R r) => "");
我试图在单个方法中编写它的原因是因为我只对lambda表达式参数感兴趣以某种方式解析它,而不是执行它。
答案 0 :(得分:4)
要直接调用此方法,您需要转换传递给特定表达式委托类型的表达式。例如:
Foo((Expression<Func<P, string>>) ((P p) => ""));
Foo((Expression<Func<P, Q, string>>) ((P p, Q q) => ""));
Foo((Expression<Func<P, Q, R, string>>) ((P p, Q q, R r) => ""));
Expression<Func<P, string>> x = (P p) => "";
Foo(x); // also fine
原因是编译器无法推断出要使用的委托类型。表达式(P p) => ""
本身没有类型,类型由上下文决定。如果您在需要委托的上下文中使用它,并且它是兼容的 - 它将是一个委托:
Func<P, string> x = (P p) => "";
MyDelegate x = (P p) => "";
如果在期望特定委托类型的表达式树的上下文中使用它 - 它将是表达式树:
Expression<Func<P, string>> x = (P p) => "";
但在你的情况下 - 无法推断出它的类型。它可以是Expression<Func<P, string>>
,Expression<MyCustomDelegate>
或其他任何内容。不同的委托类型不一样,即使它们具有相同的签名。所以你必须明确告诉它。
答案 1 :(得分:0)
是的,你可以使用如下,
Foo(Expression<Func<TEntity, bool>> query)
{
// implementation
}
将其称为
Foo((x=> x.bar == 1));
您不需要在上述方法调用中使用重载。改用这个方法并传递你想要的lambda。
希望它有所帮助:)
答案 2 :(得分:0)
使用delegate
关键字声明params
。
示例:
public delegate void ParamsAction(params object[] args);
然后:
public void Foo(object[] args)
{
...
}
使用:
ParamsAction action = Foo;
action(p);
action(p, q);
action(p, q, r);
或:
ParamsAction action1 = p => "";
ParamsAction action2 = p, q => "";
ParamsAction action3 = p, q, r => "";