1

我有一个功能:

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);

我对表达式树比较陌生,无法找到将 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);
});

但我想使用基于表达式树的方法,以消除使用反射的开销来找出调用来记录它的方法的细节的需要。

谁能建议将上述动作委托的表达式树作为方法参数传递的正确方法。

4

1 回答 1

2

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

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

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

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

恕我直言,删除模棱两可的重载并重命名其中一种方法会更好。我建议将表达式重命名为ExecuteExpression().

于 2012-05-31T03:49:47.610 回答