将过滤器应用于哪里的类属性 [英] Apply Filter to class property in Where

查看:74
本文介绍了将过滤器应用于哪里的类属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了以下RangeFilter:

I created the following RangeFilter:

public class RangeFilter<T> : IFilter<T> where T : struct, IConvertible, IComparable {

  public T? Maximum { get; private set; }
  public T? Minimum { get; private set; }

  public RangeFilter(T? minimum, T? maximum) {
    Minimum = minimum;
    Maximum = maximum;
  }

  public Boolean Matches(T value) {

    if (Minimum != null && Maximum != null)
      return value.CompareTo(Minimum) >= 0 && value.CompareTo(Maximum) <= 0;
    if (Minimum == null && Maximum != null)
      return value.CompareTo(Maximum) <= 0;

    if (Minimum != null && Maximum == null)
      return value.CompareTo(Minimum) >= 0;

    return false;

  } // Matches

} // RangeFilter

可以如下使用:

RangeFilter<Int32> filter = new RangeFilter<Int32>(2, 4);

Boolean match = filter.Matches(2);

我需要将其集成为Where扩展:

I need to integrate this as a Where extension:

public class Product {
  public Int32 Rating { get; set; }
}

List<Product> products = context.Products.Where(x => x.Rating, filter);

所以我将Filter应用于x.Rating ...的值...

So I am applying the Filter to the value of x.Rating ...

我这样做是因为我将有多个都实现IFilter的Filter类型以及其他一些东西。

I am doing it this way because I will have multiple Filter types all implementing IFilter and a few more things.

我该如何创建此扩展吗?

How can I create this extension?

推荐答案

public static class FilterExtensions
{
    public static bool Matches<T>(this T input, IFilter<T> filter) 
        where T : struct, IConvertible, IComparable
    {
        return filter.Matches(input);
    }
}

List<Product> products = context.Products.Where(x => x.Rating.Matches(filter));

List<Product> products = context.Products.Where(x => filter.Matches(x.Rating));

在您的评论中,您添加了以下内容:

In your comment you added this:


因为我将使用多种类型的过滤器,并且在
扩展名内,我将根据也会通过的
表达式确定它的过滤器类型。

Because I will have multiple types of filter and inside the Where extension I will determine which type of filter it as according to a expression I will also pass.

我不确定是否需要添加扩展名,因为在这种情况下扩展名似乎是多余的。

I'm not sure if that warrants adding an extension, since in this case the extension seems redundant.

如果您的Linq查询中有一个表达式确定要使用的过滤器,则该查询可能很难阅读。如果您确定需要基于多个属性进行过滤,则可能会变得非常混乱。

If you have an expression in your Linq query which is determining which filter to use, that query will likely be difficult to read. It could get extremely messy if you determine that you need to filter based on more than one property.

基于此,我建议为整个类定义过滤器,而不是只是一个属性。您可能有一个 IFilter< T> ,其中 T Product ,而不是 Product 的属性。

Based on that I'd recommend defining filters for the entire class, not just one property. You could have an IFilter<T> where T is Product, not a property of Product.

这使您可以将 ProductFilter 编写为可以进行单元测试的类。当您有一个条件时,该类真的很简单。如果您有更多条件,则可以修改 ProductFilter 并注入 Func< Product,bool> 的集合并运行每个产品符合条件。

That enables you to write ProductFilter as a class that you can unit test. When you have one condition that class is really simple. If you have more conditions then you can modify ProductFilter and inject a collection of Func<Product, bool> and run each Product through the conditions.

我不建议您先全力以赴。但是,如果您采用类似这些过滤器的逻辑并将它们隔离到单独的类中,那么您将完成几件事:

I wouldn't recommend going into all out overkill right up front. But if you take logic like those filters and isolate them into separate classes then you accomplish a few things:


  • 您可以对这些过滤器进行单元测试

  • 如果某个方法需要过滤器,则可以对其进行模拟,以便除过滤器之外还可以测试您的方法

  • 这将更易于阅读。 / li>
  • You can unit test those filters
  • If a method requires a filter you can mock it so that you can test your methods apart from the filters
  • It will be easier to read.

这篇关于将过滤器应用于哪里的类属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆