C#表达式指定的强制转换无效

时间:2019-10-02 14:18:43

标签: c# reflection expression

如何使用Expression.Invoke()传递参数?

如果我使用EventName = "ParameterlessAction"(尝试在无参数 Action上订阅)

-> 一切正常:可以在无参数 Action

上订阅创建的委托

但是如果我尝试使用EventName = "BoolAction"(尝试在 Action<bool> 上订阅)

-> InvalidOperationException:参数数目错误导致我不处理任何参数。

public class DelegateTest
    {
        public event Action ParameterlessAction;
        public event Action<bool> BoolAction;
        public DelegateTest()
        {
            string EventName = "ParameterlessAction";
            EventInfo eventInfo = typeof(DelegateTest).GetEvent(EventName);
            MethodInfo methodInfo = eventInfo.EventHandlerType.GetMethod("Invoke");
            var parameters = methodInfo.GetParameters();
            Type[] types = new Type[parameters.Length];
            for (int i = 0; i < types.Length; i++)
            {
                types[i] = parameters[i].ParameterType;
            }
            Delegate del = CreateDelegate(types, typeof(void));
            eventInfo.AddEventHandler(this, del);
            ParameterlessAction?.Invoke();
            BoolAction?.Invoke(false);
            BoolAction?.Invoke(true);
        }
        public void PrintMessage(string msg)
        {
            Console.WriteLine(msg);
        }
        public Delegate CreateDelegate(Type[] parameterTypes, Type returnType)
        {
            PrintMessage("Total params: " + parameterTypes.Length);
            var parameters = parameterTypes.Select(Expression.Parameter).ToArray();
            Expression body;
            if (parameters.Length == 0)
            {
                PrintMessage("Creating parameterless lambda...");
                Expression<Action> parameterlessDel = () => PrintMessage("Parameterless");
                InvocationExpression invocator = Expression.Invoke(parameterlessDel);
                body = invocator;
            }
            else if (parameters.Length == 1)
            {
                Type type = parameters[0].Type;
                if (type == typeof(bool))
                {
                    PrintMessage("Creating <bool> lambda...");
                    Expression<Action<bool>> boolDel = (b) => PrintMessage("Bool[" + b.ToString() + "]");


                    //How to pass parameter here?


                    InvocationExpression invocator = Expression.Invoke(boolDel);
                    body = invocator;
                }
                else
                {
                    throw new Exception();
                }
            }
            else
            {
                throw new Exception();
            }
            var lambda = Expression.Lambda(body, false, parameters);
            return lambda.Compile();
        }
    }

1 个答案:

答案 0 :(得分:0)

InvocationExpression invocator = Expression.Invoke(boolDel, parameters[0])