tags:

views:

438

answers:

4

I am reading the source code of subsonic 3. in the file IRepository.cs I found the following:

public interface IRepository<T>
{
    IQueryable<T> GetAll();
    PagedList<T> GetPaged<TKey>(Func<T, TKey> orderBy, int pageIndex, int pageSize);
     ...many other lines
    bool Load<T>(T item, Expression<Func<T, bool>> expression) where T : class, new();
    bool Load<T>(T item, string column, object value) where T : class, new();
}

Notice the Load methods are defined as generic and their generic type names are the same as the generic type of the interface, which cause complier warnings.

My questions is: Are the Load methods really intended to be generic or it was a mistake? If the methods were intended to be generic, should we change the type name from "T" to something different like "E" in order to make the compiler happy?

A: 

They have constraints, unlike the class-level T, so I'd guess they're supposed to be different.

Daniel Earwicker
Thanks for the hint. This brings another question:If I changed the signature into bool Load<E> ( ... ) where E : class, new();then what will the parameters be? would they bebool Load<E> (E item, Expression(Func<E, bool>> expression ) orbool Load<E> (T item, Expression(Func<T, bool>> expression ) orneither of the above?
Wei Ma
@Wei Ma - sorry, can't help further. It was just a deduction based on what's in the code you posted.
Daniel Earwicker
+1  A: 

They're not supposed to be different - Load is supposed to work on the repos "type" so you can remove the definition there (I assume that's what you're doing)

Rob Conery
So why do the declarations add their own constraints?
Daniel Earwicker
OK, I modified the code accordingly. It caused compiler errors and I had to modify a few other files to make the project compile. Will submit the changes soon so you can check if I am doing the right thing.
Wei Ma
A: 

Looks to me like the class and new constraints should be at the class level - not the method level.

Otherwise, yeah - you just defined 2 different T constraints which is just confusing as hell, since I could do this:

IRepository<int> intRepository = new RepositoryImpl<int>(); 

object o;
intRepository.Load<string>(o, "column", "value");

Having a IRepository<int> Load<string> seems rather odd to me.

It's possible that T must only be a class and new for the Load methods, but not the others. In that case, you may want something like:

interface IRepository<T> {
   IQueryable<T> GetAll();
   bool Load<TClass>(TClass item, string column, object value) where TClass : class, T, new();
}

which isn't exactly the same, since TClass could just inherit from T - but is the closest constraint I can think of to produce that result.

Mark Brackett
A: 

Well, since Rob is the author of this code. I am going to take his answer. Thanks to all you gurus for your answers.

Wei Ma