gpt4 book ai didi

c# - 使用字典作为过滤方法参数的动态 LINQ 函数

转载 作者:太空宇宙 更新时间:2023-11-03 12:59:15 26 4
gpt4 key购买 nike

我是反射区的新手。我必须通过使用它的键和值来过滤具有字典的实体列表,如下所示

public class Person
{
public string Name { get; set; }
public Dictionary<string,string> SecQuestions { get; set; }
}

以下扩展在dll中可用,无法修改

public static class extensions
{
public static List<Person> FilterMe(this List<Person> Persons, Func<Person,bool> predicate)
{
// Logic to filter the persion list
return Persons;
}
}

因此我必须使用下面的代码调用上面的方法

persons.FilterMe(xy => xy.SecQuestions.Any(x => x.Key == "PlaceOfBirth" && x.Value == "Madurai"));

我需要知道如何创建

xy => xy.SecQuestions
.Any(x => x.Key == "PlaceOfBirth" && x.Value == "Madurai")

动态使用表达式构建器作为参数传递给扩展方法。谢谢

最佳答案

var personP = Expression.Parameter(typeof(Person), "xy");            // Creates xy Parameter
var SecQuestionsProp = Expression.Property(personP, "SecQuestions"); // Creates xy.SecQuestions

var anyMethodInfo = typeof(Enumerable).GetMethods(System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public)
.Where(m => m.Name == "Any" && m.IsGenericMethod) // Search for Any methods...
.Select(m => new {
Method = m,
Params = m.GetParameters(),
Args = m.GetGenericArguments()
})
.Where(x => x.Args.Length == 1
&& x.Params.Length == 2
&& x.Params[0].ParameterType == typeof(IEnumerable<>).MakeGenericType(x.Args)
&& x.Params[1].ParameterType == typeof(Func<,>).MakeGenericType(new Type[] { x.Args.First(), typeof(bool) })) // Get the one defined as Any<TSource>(IEnumerable<TSource>, Func<TSource, bool>)
.Select(x => x.Method)
.First();

var keyValuePairP = Expression.Parameter(typeof(KeyValuePair<string, string>), "x"); // Creates x Parameter
var KeyProp = Expression.Property(keyValuePairP, "Key"); // Creates x.Key
var keyComparisonValue = Expression.Constant("PlaceOfBirth"); // Creates the value that will be compared to x.Key
var keyComparison = Expression.Equal(KeyProp, keyComparisonValue); // Creates the comparison (x.Key == "PlaceOfBirth")

var ValueProp = Expression.Property(keyValuePairP, "Value"); // Creates x.Value
var valueComparisonValue = Expression.Constant("Madurai"); // Creates the value that will be compared to x.Value
var valueComparison = Expression.Equal(ValueProp, valueComparisonValue); // Creates the comparison (x.Value == "Madurai")

var anyPredicate = Expression.Lambda(Expression.AndAlso(keyComparison, valueComparison), new ParameterExpression[] { keyValuePairP }); // Creates x => x.Key == "PlaceOfBirth" && x.Value == "Madurai"

var filterMeMethod = Expression.Lambda<Func<Person, bool>>
(Expression.Call(anyMethodInfo.MakeGenericMethod(new Type[] { typeof(KeyValuePair<string, string>) })
, new Expression[] { SecQuestionsProp, anyPredicate })
, personP); //Creates xy => xy.SecQuestions.Any(x => x.Key == "PlaceOfBirth" && x.Value == "Madurai")

var r1 = persons.FilterMe(filterMeMethod.Compile()); // Calls FilterMe with xy => xy.SecQuestions.Any(x => x.Key == "PlaceOfBirth" && x.Value == "Madurai") as parameter

关于c# - 使用字典作为过滤方法参数的动态 LINQ 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32901989/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com