从Action <T>获取参数

Ric*_*chK 6 c# reflection action

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

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"}
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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

Mar*_*ell 9

要做到这一点,它实际上应该是一个Expression<Action<T>>.然后是分解表达式的情况.幸运的是我在protobuf网,这对所有的代码在这里 -特别是ResolveMethod,它返回的值out阵列(走任何捕获变量等后).

制作后ResolveMethod的公共(和消除一切之上 ResolveMethod),代码就是:

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;
}
Run Code Online (Sandbox Code Playgroud)


Seb*_*Piu 5

它应该是这样的:

 public static object[] GetParams<T>(this T obj, Expression<Action<T>> action)
    {
        return ((MethodCallExpression) action.Body).Arguments.Cast<ConstantExpression>().Select(e => e.Value).ToArray();
    }
Run Code Online (Sandbox Code Playgroud)

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