Get parameters from action <T>
How to get parameters passed to Action<T> ? The sample code should emphasize what I'm trying to achieve. Sorry it's a little long.
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<T>(this T obj, Action<T> action) { // Return new object[]{7, "hello"} } } The only parameters that look vaguely useful are GetInvocationList (), Method, and Target. But none of them seem to contain the data I need (I think this is because of how I declared the action). Thanks
EDIT: these are not the types that I want, they are the actual values ββ- as indicated in the commented bit of code.
For this, it will actually be Expression<Action<T>> . Then this is the case of decomposition of the expression. Fortunately, I have all the code for this in protobuf-net, here in particular ResolveMethod , which returns the values ββin an out array (after passing through any captured variables, etc.).
By making ResolveMethod public (and removing everything above ResolveMethod ), the code is simply:
public static object[] GetParams<T>(this T obj, Expression<Action<T>> action) { Action ignoreThis; object[] args; ProtoClientExtensions.ResolveMethod<T>(action, out ignoreThis, out args); return args; } It should be something like this:
public static object[] GetParams<T>(this T obj, Expression<Action<T>> action) { return ((MethodCallExpression) action.Body).Arguments.Cast<ConstantExpression>().Select(e => e.Value).ToArray(); } you need to do some checking to make sure that nothing invalid can be sent to the action, since not everything will be passed to MethodCallExpression, but you should be able to follow from there
Your action x => x.Bar(7, "hello") can be rewritten as
void action(T x) { return x.Bar(7, "hello"); } It is now clear that 7 and "hello" are not action parameters, only x .
To access 7 and "hello" , you need access to an expression, such as what @Marc offers. However, it is unclear how your code should handle more complex expressions, for example x => 1 + x.Bar(7, x.Baz("hello", x.Quux(Application.Current))) .