0

How do we get benefits from generics in the following scenario?

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

What benefit do we get from first piece of code?

quetzalcoatl
  • 32,194
  • 8
  • 68
  • 107
Vikram Babu Nagineni
  • 3,411
  • 6
  • 25
  • 34
  • Maintenance, you can add as many entities you like, but this code will be universal, and reusable. This is definitely the correct path to go. [check this](https://blog.magnusmontin.net/2013/05/30/generic-dal-using-entity-framework/) – BMaximus Mar 23 '17 at 07:41
  • 1
    Possible duplicate of [What is cool about generics, why use them?](http://stackoverflow.com/questions/77632/what-is-cool-about-generics-why-use-them) -- this question ignores the "this specific scenario" (a typical one btw) that Vikram asked about, but let's face it: the advantages of generics are more or less the same. We (probably) shouldn't have hundreds of questions like "...and how about benefits in -that- case?" – quetzalcoatl Mar 23 '17 at 07:59

2 Answers2

3

Lets first look at the callers side (using option 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

Or the implementers side (using option 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
        ...
    }
}

In short, better type safety at compile time

Damien_The_Unbeliever
  • 234,701
  • 27
  • 340
  • 448
  • In the implementers side, "why do we need to check that I have been passed is really a someentity". If they dont pass Baseentity or child while calling method, they would get compile time error right? – Vikram Babu Nagineni Mar 23 '17 at 07:52
  • @VikramBabuNagineni - yes, but they might pass my `SomeEntityRepository` a `SomeOtherCompletelyUnrelatedEntity` and the compiler won't stop them. My `SomeEntityRepository` *only* wants to deal with `SomeEntity` objects. – Damien_The_Unbeliever Mar 23 '17 at 07:53
1

This would cause the developer to do un-needed castings. Consider if you want to query in the delete to check if that entity exists, how do you access entity.CustomerId for example:

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

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

While in the generic version T is of type Customer, and you don't need to do any casting in order to access the properties of that specific type.

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

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

Notice how the compiler changed all the Ts with Customer. This is one major advantage of generics, you don't need to do casting. (Same goes to the history of non-generic collections vs List<T> for example).

Zein Makki
  • 29,485
  • 6
  • 52
  • 63
  • I could not understand the advantage yet. Even in generic case, I have to cast entity as customer to access customer properties. – Vikram Babu Nagineni Mar 23 '17 at 07:48
  • @VikramBabuNagineni No, you don't have to. – Zein Makki Mar 23 '17 at 07:48
  • @VikramBabuNagineni Check the edited answer for the generic version. You can only pass an object compatible with type `Customer` to the `Customer Repository`, while in the non-generic version you could pass a `User` object to the by mistake and It would compile but fail at run-time. – Zein Makki Mar 23 '17 at 07:50