【发布时间】:2020-11-20 22:01:28
【问题描述】:
我为了好玩而进行了一些通用过滤,然后来到了某种“和”过滤器,其中约束变成了使通用代码工作的地狱。这些是我最初的通用接口:
interface ISpecification<in T>
{
bool IsSatisfied(T obj);
}
class ColoredSpecification : ISpecification<IColored>
{
readonly Color color;
public ColoredSpecification(Color color)
{
this.color = color;
}
public bool IsSatisfied(IColored iColored)
{
return iColored.Color == color;
}
}
interface IFilter<T>
{
IEnumerable<T> Filter(IEnumerable<T> items, ISpecification<T> specification);
}
class ProductFilter : IFilter<Product>
{
public IEnumerable<Product> Filter(IEnumerable<Product> items, ISpecification<Product> specification)
{
return items.Where(p => specification.IsSatisfied(p));
}
}
class GenericFilter<T> : IFilter<T>
{
public IEnumerable<T> Filter(IEnumerable<T> items, ISpecification<T> specification)
{
return items.Where(p => specification.IsSatisfied(p));
}
// It is used like this
static IEnumerable<Product> A()
{
var colorSpec = new ColoredSpecification(Color.Black);
var products = new[]
{
new Product { Color = Color.White },
new Product { Color = Color.Black },
new Product { Color = Color.Beige }
};
return new GenericFilter<Product>().Filter(products, colorSpec);
}
}
然后,有龙
class AndSpecification<T1, T2, T3, T4, T5> : ISpecification<T1>
where T1 : T2, T3
where T4 : ISpecification<T2>
where T5 : ISpecification<T3>
{
readonly T4 u;
readonly T5 v;
public AndSpecification(T4 u, T5 v)
{
this.u = u;
this.v = v;
}
public bool IsSatisfied(T1 obj)
{
return u.IsSatisfied(obj) && v.IsSatisfied(obj);
}
}
它是这样使用的:
var colorSpec = new ColoredSpecification(Color.Black);
var sizeSpec = new SizedSpecification(5);
var andSpec = new AndSpecification<Product, IColored, ISized, ColoredSpecification, SizedSpecification>(colorSpec, sizeSpec);
var products = new[]
{
new Product { Color = Color.White },
new Product { Color = Color.Black },
new Product { Color = Color.Beige }
};
return new GenericFilter<Product>().Filter(products, andSpec);
有没有合理的方法来完成这项工作?我的意思是,像 3 个泛型参数是“合理的”,或者只有 1 个,但看起来不可能
【问题讨论】:
-
您能否删除
where T1 : T2, T3,然后将ISpecification<T1>用于其他约束?