将表达式树作为Method参数传递

时间:2012-05-24 17:38:18

标签: c# expression-trees

我有一个功能:

public void Execute(Expression<Action> expression)
{
    var time = expression.Compile().Benchmark();

    var msg = string.Format("{0} took {1} to complete",
        ReflectionHelper.GetComponentCallDetails().ToString(),
        time.ToString(@"hh\:mm\:ss\.ff"));

    Logger.Info(msg);
}

需要调用的委托类似于:

channels = GetAllChannelsImpl(maxResults);

我对Expression Trees相对较新,无法找到将Action委托传递给方法的方法。

我能够使用

执行相同的功能
public void Execute(Action action)
{
    var time = action.Benchmark();

    var msg = string.Format("{0} took {1} to complete",
        ReflectionHelper.GetComponentCallDetails().ToString(),
        time.ToString(@"hh\:mm\:ss\.ff"));

    Logger.Info(msg);
}

并呼叫为

Execute(() =>
{
    channels = GetAllChannelsImpl(maxResults);
});

但我想使用基于表达式的方法,以消除使用反射开销来确定调用它的方法的详细信息。

任何人都可以建议将上述操作委托的表达式树作为方法参数传递的正确方法。

1 个答案:

答案 0 :(得分:2)

lambda表达式本身没有类型。它所采用的实际类型由编译器根据您尝试分配或强制转换的内容来推断。话虽如此,使用简单lambdas对Execute()方法的任何调用都将是不明确的,因为lambda将与ActionExpression<Action>兼容。您必须通过显式转换为您期望的类型来消除歧义。

// assign to a variable
Expression<Action> action1 = () => ...;
Execute(action1);

// cast
Execute((Expression<Action>)(() => ...));

// use the constructor
Execute(new Expression<Action>(() => ...));

删除模糊的重载并重命名其中一个方法会更好。我建议将表达式重载重命名为ExecuteExpression()