如何访问委托目标方法参数?

Gar*_*ton 2 .net c#

在以下方法中,我想访问Action中包含的任何可选参数:

public static class ValidatorEngine
{
    public static void Validate(Action someMethodWithOptionalArguments)
    {
        object target = someMethodWithOptionalArguments.Target;
    }
}
Run Code Online (Sandbox Code Playgroud)

所以如果我这样调用这个方法:

ValidatorEngine.Validate(() => UpdateByModel(model));
Run Code Online (Sandbox Code Playgroud)

我希望能够访问传递给Action的模型参数.我甚至都不想调用这个Action.

我认为可以使用Action的Target属性完成某些操作,因为我可以在调试时看到模型.我无法以编程方式弄明白.

Mar*_*ell 5

如果你想检查它但不执行它,这是一个很好的例子Expression.只需将签名更改ActionExpression<Action>.这将为您提供一个可以分析的表达式树.一个基本的例子:

public static class ValidatorEngine
{
    static void Main()
    {
        string model = "abc";
        ValidatorEngine.Validate(() => UpdateByModel(model));
    }
    public static void Validate(Expression<Action> action)
    {
        var methodCall = action.Body as MethodCallExpression;
        if (methodCall == null) throw new InvalidOperationException("Expected a method-call");
        Console.WriteLine("Method: " + methodCall.Method.DeclaringType.Name + "." + methodCall.Method.Name);
        var parameters = methodCall.Method.GetParameters();
        for (int i = 0; i < parameters.Length; i++)
        {
          Console.WriteLine(parameters[i].Name + ": " + Evaluate(methodCall.Arguments[i]));
        }
    }

    static object Evaluate(Expression exp)
    {
        switch (exp.NodeType)
        {
            case ExpressionType.Constant:
                return ((ConstantExpression)exp).Value;
            case ExpressionType.MemberAccess:
                var me = (MemberExpression)exp;
                switch (me.Member.MemberType)
                {
                    case System.Reflection.MemberTypes.Field:
                        return ((FieldInfo)me.Member).GetValue(Evaluate(me.Expression));
                    case MemberTypes.Property:
                        return ((PropertyInfo)me.Member).GetValue(Evaluate(me.Expression), null);
                    default:
                        throw new NotSupportedException(me.Member.MemberType.ToString());
                }
            default:
                throw new NotSupportedException(exp.NodeType.ToString());

        }

    }
    static void UpdateByModel(object model) {
        throw new NotImplementedException();
    }
}
Run Code Online (Sandbox Code Playgroud)

要支持更丰富的节点和方案集,请参阅此更丰富的版本.