简体   繁体   English

如何制作这种通用方法?

[英]How to make this generic method?

This is an enhancement on my previous question on specification pattern - How to combine conditions dynamically? 这是对我之前关于规范模式的问题的增强 - 如何动态组合条件? .

I am trying to make the OnSaleSpecificationForBook method a generic one. 我试图使OnSaleSpecificationForBook方法成为通用方法。 The reason being the AudioCD logic also needs a similar specification and both Book and AudioCD implements ISellingItem interface. 原因是AudioCD逻辑也需要类似的规范, BookAudioCD实现了ISellingItem接口。

Specification 规格

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

I tried to create a generic method as listed below but it throws following error: 我试图创建一个如下所列的泛型方法,但它会抛出以下错误:

The type or namespace name 'T' could not be found 找不到类型或命名空间名称“T”

Code with compilation error 代码有编译错误

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

QUESTIONS 质询

  1. What is the reason for this error? 这个错误的原因是什么?
  2. How can we make this method generic? 我们怎样才能使这个方法通用?

Note: I am using .Net 4.0. 注意:我使用的是.Net 4.0。 However I would like to know if there is any difference needed when compared with .Net 2.0 但是,我想知道与.Net 2.0相比是否需要任何差异

Abstractions 抽象

public interface ISellingItem
{
    bool IsOnSale { get; set; }
    double Price { get; set; }
}

public abstract class Specification<T>
{
    public abstract bool IsSatisfiedBy(T obj);
}

Client 客户

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();
    }
}

Entities 实体

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;
    }
}

You need to specify what the generic parameter's type is implementing before the compiler will know that it is an ISellingItem . 在编译器知道它是一个ISellingItem之前,您需要指定泛型参数的类型正在实现的ISellingItem You can do this with a where T: ISellingItem clause: 您可以使用where T: ISellingItem子句执行此操作:

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

Your class OnSaleSpecification need to define the generic parameter T and constrain it to an ISellingItem 您的OnSaleSpecification类需要定义泛型参数T并将其约束为ISellingItem

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM