C# 使用泛型类型动态构建lambda

C# 使用泛型类型动态构建lambda,c#,lambda,C#,Lambda,如何构建动态lambda函数,如下所示 item => item.AnalyzeData.Any(subitem => subitem.DepartmentIDs.Any(subitem2 => subitem2 == "abc")) AnalyzeData是自定义类数组类型,DepartmentIDs是字符串数组类型 AnalyzeData的类具有departmentid属性 因此,如何通过表达式树动态生成上述lambda表达式。经过研究,问题已经解决。现在将解决方案代码

如何构建动态lambda函数,如下所示

item => item.AnalyzeData.Any(subitem => 
subitem.DepartmentIDs.Any(subitem2 => subitem2 == "abc"))
  • AnalyzeData
    是自定义类数组类型,
    DepartmentIDs
    是字符串数组类型
  • AnalyzeData
    的类具有
    departmentid
    属性

  • 因此,如何通过表达式树动态生成上述lambda表达式。

    经过研究,问题已经解决。现在将解决方案代码共享给有问题的其他人

        [TestMethod]
        [Description("Dynamic generate lambda expression")]
    
        public void DynamicGenerateMethod1()
        {
            Item item1 = new Item()
                            {
                                ItemID = "test1",
                                AnalyzeData = new ItemAnalyzeData[]
                                                  {
                                                      new ItemAnalyzeData()
                                                          {
                                                              DepartmentIDs = new []{"Department1","Department2"}
                                                          }, 
                                                  }
                            };
            Item item2 = new Item()
            {
                ItemID = "test2",
                AnalyzeData = new ItemAnalyzeData[]
                                                  {
                                                      new ItemAnalyzeData()
                                                          {
                                                              DepartmentIDs = new []{"Department3","Department4"}
                                                          }, 
                                                  }
            };
    
    
            Expression<Func<Item, bool>> expectedExpression =
                item => item.AnalyzeData.Any(subitem => subitem.DepartmentIDs.Any(subitem2 => subitem2 == "Department3"));
            //Get Enumerable.Any generic method
            var anyPredicate =
                typeof(Enumerable).GetMethods().First(m => m.Name == "Any" && m.GetParameters().Length == 2);
    
    
    
            #region Build inner most lambda expression : subitem2 => subitem2 == "Department3"
    
            var subitem2Para = Expression.Parameter(typeof(string), "subitem2");
            var subitem2CompareValue = Expression.Equal(subitem2Para, Expression.Constant("Department3", typeof(string)));
            var subitem2CompareFun = Expression.Lambda<Func<string, bool>>(subitem2CompareValue, subitem2Para);
    
            #endregion
    
            #region Build center lambda expression : subitem => subitem.DepartmentIDs.Any( ... )
    
            var subitemPara = Expression.Parameter(typeof(ItemAnalyzeData), "subitem");
            var departmentIDsAnyMethodCall = anyPredicate.MakeGenericMethod(typeof(string));
            var subItemDepartmentIDsCall = Expression.Call(departmentIDsAnyMethodCall, Expression.Property(subitemPara, "DepartmentIDs"), subitem2CompareFun);
            var subitemCompareFun = Expression.Lambda<Func<ItemAnalyzeData, bool>>(subItemDepartmentIDsCall, subitemPara);
    
            #endregion
    
            #region Build outer most lambda expression : item => item.AnalyzeData.Any( ... )
    
            var itemExpr = Expression.Parameter(typeof(Item), "item");
            var analyzeAnyMethodCall = anyPredicate.MakeGenericMethod(typeof(ItemAnalyzeData));
            var itemAnalyzeDataCall = Expression.Call(analyzeAnyMethodCall, Expression.Property(itemExpr, "AnalyzeData"), subitemCompareFun);
            var itemCompareFun = Expression.Lambda<Func<Item, bool>>(itemAnalyzeDataCall, itemExpr);
    
            #endregion
    
            var method = itemCompareFun.Compile();
    
            var actualLambdaCode = itemCompareFun.ToString();
            var expectLambdaCode = expectedExpression.ToString();
            Assert.AreEqual(expectLambdaCode, actualLambdaCode);
            Assert.IsFalse(method.Invoke(item1));
            Assert.IsTrue(method.Invoke(item2));
    
    
    
    
        }
    
    [TestMethod]
    [说明(“动态生成lambda表达式”)]
    public void DynamicGenerateMethod1()
    {
    Item item1=新项()
    {
    ItemID=“test1”,
    AnalyzeData=新项目AnalyzeData[]
    {
    新的ItemAnalyzeData()
    {
    DepartmentIDs=new[]{“Department1”、“Department2”}
    }, 
    }
    };
    item2=新项目()
    {
    ItemID=“test2”,
    AnalyzeData=新项目AnalyzeData[]
    {
    新的ItemAnalyzeData()
    {
    DepartmentIDs=new[]{“Department3”,“Department4”}
    }, 
    }
    };
    表达式预期表达式=
    item=>item.AnalyzeData.Any(subitem=>subitem.DepartmentIDs.Any(subitem2=>subitem2==“Department3”);
    //获取可枚举的。任何泛型方法
    var任意谓词=
    typeof(Enumerable).GetMethods().First(m=>m.Name==“Any”&&m.GetParameters().Length==2);
    #区域构建最内部的lambda表达式:subitem2=>subitem2==“Department3”
    var subitem2Para=Expression.Parameter(typeof(string),“subitem2”);
    var subitem2CompareValue=Expression.Equal(subitem2Para,Expression.Constant(“Department3”,typeof(string)));
    var subitem2CompareFun=Expression.Lambda(subitem2CompareValue,subitem2Para);
    #端区
    #区域生成中心lambda表达式:subitem=>subitem.DepartmentIDs.Any(…)
    var subitemPara=表达式参数(typeof(ItemAnalyzeData),“subitem”);
    var departmentIDsAnyMethodCall=anyPredicate.MakeGenericMethod(typeof(string));
    var subItemDepartmentIDsCall=Expression.Call(departmentIDsAnyMethodCall,Expression.Property(subitemPara,“departmentid”),subitem2CompareFun);
    var subitemCompareFun=Expression.Lambda(subItemDepartmentIDsCall,subitemPara);
    #端区
    #区域构建最外层的lambda表达式:item=>item.AnalyzeData.Any(…)
    var itemExpr=Expression.Parameter(typeof(Item),“Item”);
    var analyzeAnyMethodCall=anyPredicate.MakeGenericMethod(typeof(ItemAnalyzeData));
    var itemAnalyzeDataCall=Expression.Call(analyzeAnyMethodCall,Expression.Property(itemExpr,“AnalyzeData”),subitemCompareFun);
    var itemCompareFun=Expression.Lambda(itemAnalyzeDataCall,itemExpr);
    #端区
    var method=itemCompareFun.Compile();
    var actualLambdaCode=itemCompareFun.ToString();
    var expectLambdaCode=expectedExpression.ToString();
    AreEqual(expectLambdaCode,actualLambdaCode);
    Assert.IsFalse(method.Invoke(item1));
    IsTrue(method.Invoke(item2));
    }