【问题标题】:Dynamic Build lambda with generic type具有泛型类型的动态构建 lambda
【发布时间】:2013-04-24 14:31:21
【问题描述】:

如何构建如下动态 lambda 函数?

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

那么如何通过表达式树动态生成上述 lambda 表达式。

【问题讨论】:

    标签: c# lambda


    【解决方案1】:

    经过一番研究,问题已经解决。现在将解决方案代码分享给遇到问题的其他人。

        [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));
    
    
    
    
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-13
      • 2021-06-02
      • 2018-11-13
      相关资源
      最近更新 更多