如何制作这种通用方法?

时间:2014-01-29 17:08:06

标签: c# generics

这是我之前关于规范模式的问题的增强 - How to combine conditions dynamically?

我正在努力使OnSaleSpecificationForBook方法成为通用方法。 AudioCD逻辑的原因还需要类似的规范,BookAudioCD都实现ISellingItem接口。

规范

public class OnSaleSpecificationForBook : Specification<Book>
{
    public override bool IsSatisfiedBy(Book product)
    {
        return product.IsOnSale;
    }
}

我尝试创建一个如下所列的泛型方法,但它会抛出以下错误:

  

无法找到类型或命名空间名称“T”

包含编译错误的代码

public class OnSaleSpecification : Specification<T>
{
    public override bool IsSatisfiedBy(T item)
    {
        return item.IsOnSale;
    }
}

问题

  1. 出现此错误的原因是什么?
  2. 我们如何使这种方法通用?
  3. 注意:我使用的是.Net 4.0。但是,我想知道与.Net 2.0相比是否需要任何差异

    抽象

    public interface ISellingItem
    {
        bool IsOnSale { get; set; }
        double Price { get; set; }
    }
    
    public abstract class Specification<T>
    {
        public abstract bool IsSatisfiedBy(T obj);
    }
    

    客户端

    class Program
    {       
        static void Main(string[] args)
        {
            List<Book> list = new List<Book>();
    
            Book p1 = new Book(false, 99);
            Book p2 = new Book(true, 99);
            Book p3 = new Book(true, 101);
    
            list.Add(p1);
            list.Add(p2);
            list.Add(p3);
    
            var specification = new OnSaleSpecificationForBook();
            List<Book> selectedList =
                ProductFilterHelper.GetProductsUisngDynamicFilters(list, specification);
        }
    }
    
    public static class ProductFilterHelper
    {
        public static List<Book> GetProductsUisngDynamicFilters(List<Book> productList, Specification<Book> productSpecification)
        {
            return productList.Where(p => productSpecification.IsSatisfiedBy(p))
                              .ToList();
        }
    }
    

    实体

    public class Book : ISellingItem
    {
        public bool IsOnSale { get; set; }
        public double Price { get; set; }
    
        public Book(bool isOnSale, double price)
        {
            this.Price = price;
            this.IsOnSale = isOnSale;
        }
    }
    
    public class AudioCD : ISellingItem
    {
        public bool IsOnSale { get; set; }
        public double Price { get; set; }
    
        public AudioCD(bool isOnSale, double price)
        {
            this.Price = price;
            this.IsOnSale = isOnSale;
        }
    }
    

2 个答案:

答案 0 :(得分:3)

在编译器知道它是ISellingItem之前,您需要指定泛型参数的类型正在实现的内容。您可以使用where T: ISellingItem子句执行此操作:

public class OnSaleSpecification<T> : Specification<T> where T : ISellingItem
{
    public override bool IsSatisfiedBy(T item)
    {
        return item.IsOnSale;
    }
}

答案 1 :(得分:0)

你的OnSaleSpecification类需要定义泛型参数T并将其约束为ISellingItem

public class OnSaleSpecification<T> : Specification<T> where T : ISellingItem
{
    public override bool IsSatisfiedBy(T item)
    {
        return item.IsOnSale;
    }
}