我可以向IEnumerable.Any方法的LINQ查询中动态添加参数吗?

时间:2019-04-25 10:42:06

标签: c# linq

我创建了一个接受动态列表,一个对象和两个参数名称的方法。我想使用Enumerable.Any方法返回一个布尔值,该方法具有基于传递给此方法的参数名称的匹配条件。

public static bool CheckDuplicate(List<T> list, Object obj, string param1, string param2)
{
    return list.Any(item => item.pararm1 = obj.param1 && item.param2 = obj.param2);
}

我想根据动态提供的条件找到与obj对象的值匹配的项目。

2 个答案:

答案 0 :(得分:1)

考虑创建类似LINQ的扩展方法WhereAll,该方法对所有作为参数给出的谓词进行Where

static IEnumerable<TSource> WhereAll<TSource>(this IEnumerable<TSource> source
   IEnumerable<Func<TSource, bool>> predicates)
{
    // TODO: exception if source / predicates null

    // return all source elements that have a true for all predicates:
    foreach (var sourceElement in source)
    {
        // check if this sourceElement returns a true for all Predicates:
        if (predicates.All(predicate => predicate(sourceElement))
        {
             // yes, every predicate returns a true
             yield return sourceElement;
        }
        // else: no there are some predicates that return false for this sourceElement
        // skip this element
 }

用法:

List<Person> persons = ...
// Get all Parisians with a Name that were born before the year 2000:
var result = persons.WhereAll(new Func<Person, bool>[]
    {
         person => person.Name != null,
         person => person.BirthDay.Year < 2000,
         person => person.Address.City == "Paris",
    });

答案 1 :(得分:1)

似乎想要的是比较成员变量的 name 访问的成员变量。这就是反射。这是我的解决方案:

首先添加一个扩展方法,以帮助我们按名称获取成员变量(来自this SO answer):

static class Extension
{
    public static object GetPropValue(this object src, string propName)
    {
        return src.GetType().GetProperty(propName).GetValue(src, null);
    }
}

然后,您的功能将是:

public static bool CheckDuplicate<T>(IEnumerable<T> list, object obj, string param1, string param2)
    {
        return list.Any(item =>
        item.GetPropValue(param1).Equals(obj.GetPropValue(param1)) &&
        item.GetPropValue(param2).Equals(obj.GetPropValue(param2))
        );
    }

我以此测试了功能。它打印True

static void Main(string[] args)
    {
        var theList = Enumerable.Range(0, 10).Select(i => new Tuple<int, int>(i, i + 1));
        Console.WriteLine(CheckDuplicate(theList, new { Item1 = 5, Item2 = 6 }, "Item1", "Item2"));
        Console.ReadKey();
    }

但是,要在生产中使用,您可能需要确保param1param2实际上存在,并且还请查找并考虑.Equals()和{{1}之间的区别}。注意==的返回值被加框。