我创建了以下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扩展名:
public class Product {
public Int32 Rating { get; set; }
}
List<Product> products = context.Products.Where(x => x.Rating, filter);
所以我将Filter应用于x.Rating的值......
我这样做是因为我将有多个Filter类型都实现IFilter和更多东西。
如何创建此扩展程序?
答案 0 :(得分:1)
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));
在评论中添加了以下内容:
因为我将在Where里面有多种类型的过滤器 扩展我将根据a确定哪种类型的过滤器 表达我也会通过。
我不确定是否需要添加扩展名,因为在这种情况下,扩展名似乎是多余的。
如果您的Linq查询中有一个表达式确定要使用哪个过滤器,则该查询可能难以阅读。如果您确定需要根据多个属性进行过滤,则可能会非常混乱。
基于此,我建议为整个类定义过滤器,而不仅仅是一个属性。您可以IFilter<T>
T
Product
,而不是Product
的属性。
这使您可以将ProductFilter
编写为可以进行单元测试的类。当你有一个条件,这个类非常简单。如果您有更多条件,则可以修改ProductFilter
并注入Func<Product, bool>
的集合,并在条件下运行每个Product
。
我不建议在前面进行全面的过度杀伤。但是如果你像那些过滤器一样采用逻辑并将它们分成不同的类,那么你就完成了一些事情: