从Action 获取参数

如何将参数传递给Action ? 代码示例应该突出我想要实现的目标。 对不起,这有点长。

 class Program { static void Main(string[] args) { Foo foo = new Foo(); foo.GetParams(x => x.Bar(7, "hello")); } } class Foo { public void Bar(int val, string thing) { } } static class Ex { public static object[] GetParams(this T obj, Action action) { // Return new object[]{7, "hello"} } } 

看起来有用的唯一选项是GetInvocationList(),Method和Target。 但它们似乎都没有包含我所追求的数据(我认为这是因为我宣布了Action的方式)。 谢谢

编辑:这不是我想要的类型,它是实际值 – 如注释的代码中所述。

要做到这一点,它实际上应该是一个Expression> 。 然后是分解表达式的情况。 幸运的是,我在protobuf-net中拥有了所有代码 – 特别是ResolveMethod ,它返回out数组中的值(在遍历任何捕获的变量之后等)。

在将ResolveMethod公开(并删除ResolveMethod 上面的所有内容)后,代码只是:

 public static object[] GetParams(this T obj, Expression> action) { Action ignoreThis; object[] args; ProtoClientExtensions.ResolveMethod(action, out ignoreThis, out args); return args; } 

它应该是这样的:

  public static object[] GetParams(this T obj, Expression> action) { return ((MethodCallExpression) action.Body).Arguments.Cast().Select(e => e.Value).ToArray(); } 

你应该做一些检查,以确认没有任何无效的东西可以发送到动作,因为不是所有的东西都会被转换为MethodCallExpression,但你应该能够从那里开始

您的操作x => x.Bar(7, "hello")可以重写为

 void action(T x) { return x.Bar(7, "hello"); } 

现在很清楚, 7"hello"不是动作的参数,只有x是。

为了能够访问7"hello" ,你需要访问表达式,就像@Marc建议的那样。 但是,不清楚你的代码应该如何处理更复杂的表达式,比如x => 1 + x.Bar(7, x.Baz("hello", x.Quux(Application.Current)))