例子:对应 https://www.cnblogs.com/Zingu/p/16256988.html
enum Color { Yellow, Red, Green } enum Size { Small, Medium, Large, Yuge } class Product { public string Name; public Color Color; public Size Size; public Product(string name, Color color, Size size) { Name = name; Color = color; Size = size; } public override string ToString() { return $" -I'm Has a {Size} {Name} ,I't {Color}"; } } class ProductFilter { public static IEnumerable<Product> FilterBySize(IEnumerable<Product> products, Size size) { foreach (var item in products) if (item.Size == size) yield return item; } } interface ISpecification<T> { bool IsSatified(T t); } interface IFilter<T> { IEnumerable<T> Filter(IEnumerable<T> items, ISpecification<T> spec); //IEnumerable<T> FilterMore(IEnumerable<T> items, ISpecification<T> spec1, ISpecification<T> spec2); } class ColorSpecification : ISpecification<Product> { private Color Color; public ColorSpecification(Color color) { Color = color; } public bool IsSatified(Product t) { return t.Color == Color; } } class SizeSpecification : ISpecification<Product> { private Size size; public SizeSpecification(Size size) { this.size = size; } public bool IsSatified(Product t) { return t.Size == size; } } class CompSiteSpecification<T> : ISpecification<T> { private IEnumerable<ISpecification<T>> specifications; public CompSiteSpecification(params ISpecification<T>[] _specifications) { specifications = _specifications; } public bool IsSatified(T t) { return specifications.All(sp => sp.IsSatified(t)); } } class AndSpecification<T> : ISpecification<T> { ISpecification<T> specification1, specification2; public AndSpecification(ISpecification<T> specification1, ISpecification<T> specification2) { this.specification1 = specification1; this.specification2 = specification2; } public bool IsSatified(T t) { return specification1.IsSatified(t) && specification2.IsSatified(t); } } class BetterFilter : IFilter<Product> { public IEnumerable<Product> Filter(IEnumerable<Product> items, ISpecification<Product> spec) { foreach (var item in items) { if (spec.IsSatified(item)) { yield return item; } } } //public IEnumerable<Product> FilterMore(IEnumerable<Product> items, ISpecification<Product> spec1, ISpecification<Product> spec2) //{ // foreach (var item in items) // { // if (spec1.IsSatified(item)&& spec2.IsSatified(item)) // { // yield return item; // } // } //} } internal class Program { static void Main(string[] args) { Product apple = new Product("Apple", Color.Red, Size.Small); Product banana = new Product("Banana", Color.Yellow, Size.Medium); Product home = new Product("Home", Color.Green, Size.Large); Product tree = new Product("Tree", Color.Green, Size.Large); Product greenApple = new Product("GreenApple", Color.Green, Size.Small); Product[] products = { apple, banana, home, tree, greenApple }; Console.WriteLine("Get Large (new):"); foreach (var item in ProductFilter.FilterBySize(products, Size.Large)) { Console.WriteLine(item); } BetterFilter better = new BetterFilter(); Console.WriteLine("Get Large (new):"); foreach (var item in better.Filter(products, new ColorSpecification(Color.Green))) { Console.WriteLine(item); } Console.WriteLine("Get Green & Small (new):"); foreach (var item in better.Filter(products, new CompSiteSpecification<Product>( new ColorSpecification(Color.Green), new SizeSpecification(Size.Small))) ) { Console.WriteLine($" -{item.Name} is big & Green"); } } }