【问题标题】:Building expression tree with LINQ Min method - throws ArgumentException使用 LINQ Min 方法构建表达式树 - 引发 ArgumentException
【发布时间】:2012-10-30 13:14:56
【问题描述】:
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;

namespace Test_console_application
{
    class Program
    {
        static void Main(string[] args)
        {
            var parentPropertyName = "Measurements";
            var parentPropertyType = typeof (Measurement);
            var propertyName = "Data";

            var parameterExp = Expression.Parameter(typeof(Inverter), "type");
            var propertyExp = Expression.Property(parameterExp, parentPropertyName);

            var method = typeof(Enumerable).GetMethods(BindingFlags.Static | BindingFlags.Public)
                .Single(x => x.ToString() == "Double Min[TSource](System.Collections.Generic.IEnumerable`1[TSource], System.Func`2[TSource,System.Double])")
                .MakeGenericMethod(parentPropertyType);

            var minParameterExp = Expression.Parameter(parentPropertyType, "type2");
            var minPropertyExp = Expression.Property(minParameterExp, propertyName);
            var minMethodExp = Expression.Call(method, propertyExp, minPropertyExp);            
        }
    }

    public class Inverter
    {
        public IList<Measurement> Measurements { get; set; }
    }

    public class Measurement
    {
        public double Data { get; set; }
    }
}

当我运行这段代码时,我得到一个 ArgumentException:

“System.Double”类型的表达式不能用于参数 类型 'System.Func2[Test_console_application.Measurement,System.Double]' of method 'Double Min[Measurement](System.Collections.Generic.IEnumerable1[Test_console_application.Measurement], System.Func`2[Test_console_application.Measurement,System.Double])'

我明白它的意思,但我只是认为我是用 minPropertyExp 做的。
我不知道我需要改变什么 - 有什么线索吗?

【问题讨论】:

    标签: c# reflection lambda expression-trees


    【解决方案1】:

    您不应将属性表达式作为 Func 传递。你应该传递一个方法。

    你做了类似的事情:

    Measurements.Min(type2.Data)
    

    代替

    Measurements.Min(x => x.Data)
    

    来自 Morten Holmgaard 的评论

    var minMethod = Expression.Lambda(minPropertyExp, minParameterExp);
    var minMethodExp = Expression.Call(method, propertyExp, minMethod);
    

    【讨论】:

    • 但是我该如何创建这个方法 - 使用反射?
    • 好的,我解决了这个问题:var minMethod = Expression.Lambda(minPropertyExp, minParameterExp); var minMethodExp = Expression.Call(method, propertyExp, minMethod);
    • @Morten:太好了,我不知道该怎么做,但希望我的回答无论如何都会有所帮助:-) 已将您的解决方案添加到答案中。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-28
    • 2018-09-17
    • 2017-09-24
    相关资源
    最近更新 更多