如何从Action类型变量中获取所有参数

时间:2018-02-16 13:38:24

标签: c# .net lambda

我需要构建一个跟踪,可以记录Action代码变量中传递的所有参数。

如果动作变量填充了lambda表达式,如何从Action实例中获取所有参数?

更新(澄清行动对象的使用)

我在我试图构建的API跟踪器下面发布。 API跟踪器需要从操作对象中传递的lambda表达式中获取参数:

public static class Tracer
{
    public static void log(Action action)
    {
      // note that action will always be set with a lambda function. See ServiceProxy class bellow.
      //..grab the action parameters and name and log them
    }
}

我只找到了从表达式中获取这些信息的方法。从动作类型对象,我没有找到它保存参数,只找到方法名称。

此Tracer将在公开服务的Proxy类中使用。应记录所有呼叫。 Proxy使用调用服务的函数包装器,如下所示:

class ServiceProxy:IServiceProxy {
   ...
   private void CallWrapper(Action func)
   {
        try
        {
            Tracer.log(func);
            func();
        }
        catch (Exception ex){...}
    }

    //method call example
    public void IServiceProxy.RequestX(String p1, int p2){
           CallWrapper(() =>  service.RequestX(p1, p2));//p1 and p2 parametersshould be logged by the Tracer.
    }       
}

为了重用CallWrapper方法,lambda表达式签名必须是动态的,这意味着func类型不能声明为泛型(例如:Action<String,Int>)。< / p>

1 个答案:

答案 0 :(得分:0)

您可以使用Linq.Expressions提取您的参数 这意味着您需要将null更改为Action Aftre这样做,你将能够通过自定义表达式访问者浏览你的lambda。

让我们首先添加一个可以检查表达式的新类:

Expression<Action>

现在我们可以在public class ArgumentExtractor : System.Linq.Expressions.ExpressionVisitor { private Dictionary<string, object> arguments; public IDictionary<string, object> Arguments => arguments; protected override Expression VisitMethodCall(MethodCallExpression node) { arguments = node.Arguments .Select(a => { var memeber = a as MemberExpression; if (memeber == null) return null; var name = memeber.Member.Name; var container = (memeber.Expression as ConstantExpression)?.Value; var value = container.GetType().GetField(name).GetValue(container); return new {name, value}; }) .Where(x => x != null) .ToDictionary(x => x.name, x => x.value); return base.VisitMethodCall(node); } }

中使用它了
Tracer

最后我们需要修改public static class Tracer { public static void log(Expression<Action> action) { var argumentExtractor = new ArgumentExtractor(); argumentExtractor.Visit(action); var arguments = argumentExtractor.Arguments; // to do: write it to log } }

CallWrapper

您可以找到完整的演示here