使用动态布尔运算符过滤对象列表

时间:2014-03-21 12:16:37

标签: c# linq list

我有这个方法:

private static List<ObjectA> ListItemsToShow(IEnumerable<ObjectA> listObjectB, 
                                             string _rarity, 
                                             string _type, 
                                             string _color,
                                             int? _quantity, 
                                             int? _sold, 
                                             string _quantitySymbol,
                                             string _soldSymbol)
{
    List<ObjectA> listToReturn = (from item in listObjectB 
                                  where _rarity == "All" || item.rarity == _rarity
                                  where _type == "All" || item.Type.Contains(_type) 
                                  where _color == "All" || item.Color.Contains(_color) 
                                  where _quantity == null || item.NbInStock == (int)_quantity
                                  where _sold == null || item.QtySold == (int)_sold
                                  select item).ToList();
    return listToReturn;
}

到目前为止它完成了工作:基于静态的对象列表,它返回可以从原始对象列表中过滤的内容。

现在我想添加一个动态参数:quantitySymbol和soldSymbol。每个都是其中一个选择:

  • &GT;
  • &LT;
  • &GT; =
  • &LT =

例如,我可能会获得NbInStock <><=>=的所有项目,而不是原始项目中保留的项目名单。同样适用于QtySold属性。

我在如何在linq声明中做到这一点时遇到了一些麻烦,我需要帮助来解决这个问题。

1 个答案:

答案 0 :(得分:3)

您可以使用功能进行过滤:

List<ObjectA> ItemsToShow(IEnumerable<ObjectA> listObjectB, Func<int,bool> stockFilter) {
  return (
    from item in listObjectB
    where (stockFilter == null || stockFilter(item.NbInStock)
    select item
  ).ToList();
}

并像这样使用它:

ItemsToShow(data, stock => (stock <= 10));
ItemsToShow(data, stock => (stock == 25));
ItemsToShow(data, stock => (stock > 3));
ItemsToShow(data, null); // does not use a stock filter

如果您需要从字符串创建库存过滤器,可以使用工厂函数:

Func<int,bool> CreateCompareFilter(string op, int? quantity) {
   if(quantity == null) return null;
   if(op == "==") return x => (x == quantity);
   if(op == "<") return x => (x < quantity);
   ...
   return null;
}

然后你可以写

ItemsToShow(data, CreateCompareFilter("==",10));

总的来说,这看起来像这样:

private static List<ObjectA> ListItemsToShow(IEnumerable<ObjectA> listObjectB, 
                                             string _rarity, 
                                             string _type, 
                                             string _color,
                                             Func<int,bool> _stockFilter,
                                             Func<int,bool> _soldFilter)
{
    return (
        from item in listObjectB 
        where _rarity == "All" || item.rarity == _rarity
        where _type == "All" || item.Type.Contains(_type) 
        where _color == "All" || item.Color.Contains(_color) 
        where _stockFilter == null || _stockFilter(item.NbInStock)
        where _soldFilter == null || _soldFilter(item.QtySold)
        select item
    ).ToList();
}

ListItemsToShow(data, rarity, type, color,
   CreateCompareFilter(_quantitySymbol,_quantity)
   CreateCompareFilter(_soldSymbol,_sold));