Reputation: 22652
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. The reason being the AudioCD logic also needs a similar specification and both Book
and AudioCD
implements ISellingItem
interface.
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
Code with compilation error
public class OnSaleSpecification : Specification<T>
{
public override bool IsSatisfiedBy(T item)
{
return item.IsOnSale;
}
}
QUESTIONS
Note: I am using .Net 4.0. However I would like to know if there is any difference needed when compared with .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;
}
}
Upvotes: 3
Views: 103
Reputation: 12700
Your class OnSaleSpecification need to define the generic parameter T and constrain it to an ISellingItem
public class OnSaleSpecification<T> : Specification<T> where T : ISellingItem
{
public override bool IsSatisfiedBy(T item)
{
return item.IsOnSale;
}
}
Upvotes: 0
Reputation: 6181
You need to specify what the generic parameter's type is implementing before the compiler will know that it is an ISellingItem
. You can do this with a where T: ISellingItem
clause:
public class OnSaleSpecification<T> : Specification<T> where T : ISellingItem
{
public override bool IsSatisfiedBy(T item)
{
return item.IsOnSale;
}
}
Upvotes: 3