C# 使用泛型类型动态构建lambda
如何构建动态lambda函数,如下所示C# 使用泛型类型动态构建lambda,c#,lambda,C#,Lambda,如何构建动态lambda函数,如下所示 item => item.AnalyzeData.Any(subitem => subitem.DepartmentIDs.Any(subitem2 => subitem2 == "abc")) AnalyzeData是自定义类数组类型,DepartmentIDs是字符串数组类型 AnalyzeData的类具有departmentid属性 因此,如何通过表达式树动态生成上述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));
}