views:

667

answers:

2

I had this code from a previous question, but its not compiling:

    public interface IEntity
{     
// Common to all Data Objects
}
public interface ICustomer : IEntity
{
     // Specific data for a customer
}
public interface IRepository<T, TID> : IDisposable where T : IEntity
{
     T Get(TID key);
     IList<T> GetAll();
     void Save (T entity);
     T Update (T entity);
     // Common data will be added here
}
public class Repository<T, TID> : IRepository
{
     // Implementation of the generic repository
}
public interface ICustomerRepository
{
     // Specific operations for the customers repository
}
public class CustomerRepository : Repository<ICustomer>, ICustomerRepository
{
     // Implementation of the specific customers repository
}

But in these 2 lines :

1- public class Repository : IRepository

2- public class CustomerRepository : Repository, ICustomerRepository

It give me this error: Using the generic type 'TestApplication1.IRepository' requires '2' type arguments

can you help me solve?

+1  A: 

When you are implementing a generic interface, you need to provide the generic interface type specifications as well. Change those two lines to:

public class Repository<T, TID> : IRepository<T, TID>
     where T : IEntity
{  
    // ...

and

public class CustomerRepository : Repository<ICustomer, int /*TID type*/>, ICustomerRepository
{
     // ...
Reed Copsey
now giving this error: The type 'T' cannot be used as type parameter 'T' in the generic type or method 'TestApplication1.IRepository<T,TID>'. There is no boxing conversion or type parameter conversion from 'T' to 'TestApplication1.IEntity'.
Amr ElGarhy
Sorry - I edited my answer. You have to put the constraint for T : IEntity in Repository, as well. I forgot to include that.
Reed Copsey
+3  A: 

You need to use two type arguments when inheriting from Repository/IRepository because they take take two type arguments. Namely, when you inherit from IRepository, you need to specify something like:

public class Repository<T, TID> : IRepository<T,TID> where T:IEntity

and

public class CustomerRepository : Repository<ICustomer,int>,ICustomerRepository

Edited to add type constraint on implementation of Reposistory

JasonTrue
ICustomerRepository is non-generic in his code.
Reed Copsey
ah, yes, just noticed that as I clicked Submit...
JasonTrue
now giving this error: The type 'T' cannot be used as type parameter 'T' in the generic type or method 'TestApplication1.IRepository<T,TID>'. There is no boxing conversion or type parameter conversion from 'T' to 'TestApplication1.IEntity'.
Amr ElGarhy
A missed detail, sorry. Your type constraints aren't going to be inherited, so you need to specify them again. In your Repository generic class, add where T : IEntity after IRepository<T,TID>
JasonTrue
But now i have another problem, that i can't implement GetAll function inside the CustomerRepository , how to declare it there while CustomerRepository not inherting IReprository
Amr ElGarhy
I'm not sure why you'd want to do that, since based on your code, it appears to be implemented in your base class, Repository<T,TID>. If you are unhappy with the base class implementation in the context of CustomerRepository, you can use public new IList<ICustomer> GetAll() to hide the original implementation.
JasonTrue
Alternatively, you can make IList<T> GetAll() virtual in your base class, and use the override keyword in subclasses that need to behave differently.
JasonTrue