是否可以使用' lambda表达式参数调用方法'?

时间:2018-03-10 19:14:00

标签: c# lambda expression

我们说我的方法有以下签名:

public string Foo(Expression expression)
{
    ...
}

是否可以直接调用此方法,而不使用代理方法,如果是,如何?

作为一个额外的问题(要理解我为什么要这样做),是否可以声明一个方法(没有重载),在所有这些情况下都会调用它:

Foo(P p => "");
Foo((P p, Q q) => "");
Foo((P p, Q q, R r) => "");

我试图在单个方法中编写它的原因是因为我只对lambda表达式参数感兴趣以某种方式解析它,而不是执行它。

3 个答案:

答案 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 => "";