簡體   English   中英

C#表達式調用,似乎無法正確獲取方法信息和參數

[英]C# Expression Call, Can't seem to get the method info and parameters correct

Expression> lambda = Expression.Lambda>(methodCall,allParameters);這是錯誤:

在以下情況中發生了類型'System.ArgumentException'的異常:其他信息:類型'System.Func`2 [Business.Entities.SlateEmployee,Sy​​stem.Boolean]'的表達式不能用於返回類型'System.Boolean'

誰能看到我的代碼出了什么問題。

    public class ClearValueAction : ActionRuleBase
    {
        /// <summary>
        /// Virtual method to call during actions
        /// </summary>
        /// <returns></returns>
        public override bool ExecuteAction<T>(T dataObject)
        {
            PropertyInfo propertyInfo = typeof (T).GetProperty(Left);
            if (propertyInfo != null)
            {
                ReflectionUtils.SetObjectValue(dataObject, null, propertyInfo);
                return true;
            }
            return false;
        }

        /// <summary>
        /// Making an expression to call the ExecuteAction function when this is compiled
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public override Func<T, bool> CompileRule<T>()
        {

            //return Expression.Lambda<Func<T, bool>>().Compile();
                ParameterExpression allParameters;
                var methodCall = CreateLambda<T>("ExecuteAction", "dataObject", out allParameters);


    //ERROR IS HERE//////////////////////////////////////////////
               Expression<Func<T, bool>> lambda = Expression.Lambda <Func<T, bool>>(methodCall, allParameters);
            return lambda.Compile();

        }

        private LambdaExpression CreateLambda<T>(string methodName, string methodInputParamName, out ParameterExpression allParameters)
        {

            allParameters = Expression.Parameter(typeof(T), methodInputParamName);
            var c = Expression.Constant(methodInputParamName);
            MethodInfo methodInfo = typeof(ClearValueAction).GetMethods().First(m => m.Name == methodName && m.IsGenericMethod).MakeGenericMethod(typeof(T));
            MethodCallExpression generateCallExpression = GenerateCallExpression(this, methodInfo, allParameters);
            return Expression.Lambda(generateCallExpression, allParameters);
        }

        /// <summary>
        /// Generate expression call
        /// </summary>
        /// <param name="instance">If instance is NULL, then it method will be treated as static method</param>
        private static MethodCallExpression GenerateCallExpression(object instance, MethodBase method, ParameterExpression allParameters)
        {
            var methodInfo = method as MethodInfo;
            // it's non static method
            if (instance != null)
            {
                var instanceExpr = Expression.Convert(Expression.Constant(instance), instance.GetType());
                return Expression.Call(instanceExpr, methodInfo, allParameters);
            }

            // it's static method
            return Expression.Call(methodInfo, allParameters);
        }

        private static List<Expression> GenerateParameters(MethodBase method, out ParameterExpression allParameters)
        {
            allParameters = Expression.Parameter(typeof(object[]), "params");
            ParameterInfo[] methodMarameters = method.GetParameters();
            List<Expression> parameters = new List<Expression>();
            for (int i = 0; i < methodMarameters.Length; i++)
            {
                var indexExpr = Expression.Constant(i);
                var item = Expression.ArrayIndex(allParameters, indexExpr);
                var converted = Expression.Convert(item, methodMarameters[i].ParameterType);
                parameters.Add(converted);
            }

            return parameters;
        }
}

您的CreateLambda<T>()函數已經在生成一個lambda表達式。 通過對結果調用Expression.Lambda<>() ,您試圖創建一個返回lambda表達式的lambda表達式。

只需對其進行更改,以使您在編譯時就知道它是哪種類型的表達式:

private Expression<Func<T, bool>> CreateLambda<T>(string methodName, string methodInputParamName, out ParameterExpression allParameters)
{
    allParameters = Expression.Parameter(typeof(T), methodInputParamName);
    var c = Expression.Constant(methodInputParamName);
    MethodInfo methodInfo = typeof(ClearValueAction).GetMethods().First(m => m.Name == methodName && m.IsGenericMethod).MakeGenericMethod(typeof(T));
    MethodCallExpression generateCallExpression = GenerateCallExpression(this, methodInfo, allParameters);
    return Expression.Lambda<Func<T, bool>>(generateCallExpression.Dump(), allParameters);
}

然后直接編譯該結果:

public Func<T, bool> CompileRule<T>()
{
    ParameterExpression allParameters;
    var methodCall = CreateLambda<T>("ExecuteAction", "dataObject", out allParameters);
    return methodCall.Compile();
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM