我们如何从IRepository <t> CRUD场景中的泛型中获益?

时间:2017-03-23 07:30:26

标签: c# generics

在以下情况下,我们如何从泛型中获益?

public interface IRepository<T> where T : BaseEntity 
{ 
        IEnumerable<T> GetAll(); 
        T Get(long id); 
        void Insert(T entity);         
        void Update(T entity); 
        void Delete(T entity); 
} 


public interface IRepository
{
       IEnumerable<BaseEntity> GetAll(); 
        BaseEntity Get(long id); 
        void Insert(BaseEntity entity);         
        void Update(BaseEntity entity); 
        void Delete(BaseEntity entity); 
}

我们从第一段代码中获得了什么好处?

2 个答案:

答案 0 :(得分:3)

让我们先看一下来电者(使用选项1):

IRepository<SomeEntity> x = ...

var se = x.Get(19);

//I can now immediately call SomeEntity specific methods on se
//Without any casts, and I know it's a SomeEntity and not some other type

或实施者方(使用选项2):

class SomeEntityRepository : IRepository {

    ...

    void Insert(BaseEntity entity) {
        //Now I need to check that what I've been passed is
        //really a SomeEntity, since that's what I'm a repository for
        ...
    }
}

简而言之,在编译时更好的类型安全性

答案 1 :(得分:1)

这会导致开发人员进行不需要的铸件。考虑是否要在删除中查询以检查该实体是否存在,例如如何访问entity.CustomerId

public CustomerRepository : IRepository
{
   /* other methods here */

   void Delete(BaseEntity entity)
   {
      var customer = entity as Customer;
      // query for customer.CustomerId;
   }
}

虽然通用版T的类型为Customer,但您无需进行任何投射即可访问该特定类型的属性。

public CustomerRepository : IRepository<Customer>
{
   /* other methods here */

   void Delete(Customer entity)
   {
      // No casting
      // query for entity.CustomerId;
   }
}

注意编译器如何使用T更改了所有Customer s。这是仿制药的一个主要优点,您不需要进行铸造。 (例如,非通用集合与List<T>的历史相同)。