Rishi Jhaver


Hi

I just started working with generics and am stuck at a basic problem.

Have a base class - BaseObject

Have 3 derived classes from this - User, Product and Site.

Now, I have a ReturnObject method that returns a generic of BaseObject (List<BaseObject>)

But I really am returning List<User> from this method

This is the code from User.cs:

public List<BaseObject> ReturnObject()

{

//...do something

return List<User>;

}

So my return type is a generic of the base and I actually want to return a generic of the derived class.

Is there any way to do this

Also in my main program.cs, I have

List<User> u = ReturnObject()

The above line gives an error. It says that I cannot assign a generic base to a generic derived object.

Now I want to pass a collection of child and I want to declare the return type as collection of base class.

Is there anyway I can do this

I think I can get this done using arrays, but I would really like to use generics.

Thanks for your help

Rishi...




Re: Question regarding Generics and Inheritance

michhes


Hi Rishi,

The list you're returning is declared as a list of BaseObjects and you're trying to return a list of User objects (or whatever) and that's not going to work. I'd suggest creating a new list of BaseObjects and adding your User object to it. You'll then be returning List<BaseObject>, as specified in your method signature. It's a bit of a hassle and even more so when you want to be working with a list of Users outside your ReturnObject() method.






Re: Question regarding Generics and Inheritance

Peter Ritchie

Right, an instantiation of a generic type using a base type and a derived type does not mean those two types have an inheritance or obtain an inheritance from the relationship of the two parametrized types.





Re: Question regarding Generics and Inheritance

James Curran

Let's see if I can put together the missing pieces here.....

class BaseObject

{
abstract List<BaseObject> ReturnObject();

}

class User : BaseObject

{

public List<BaseObject> ReturnObject()

{ ....... return List<User>(); }

}

This can be handle through a technique called "The Curiously Reoccuring Template Pattern":

class BaseObject<T>

{
abstract List<T> ReturnObject();

}

class User : BaseObject<User>

{

public List<User> ReturnObject()

{ ....... return List<User>(); }

}






Re: Question regarding Generics and Inheritance

michhes

Code Snippet

class BaseObject

{
abstract List ReturnObject();

}

class User : BaseObject

{

public List ReturnObject()

{ ....... return List(); }

}

This compiles and runs but I'm not convinced it provides a realistic solution to the problem... the List returned simply is not a list of BaseObjects--for instance, we can't call User.ReturnObject () and expect to store the results in a variable typed as List<BaseObject>. If we dig a bit deeper with this code sample and try to add a second method that returns another generic list of a different type, then we end up also having to list those types in the BaseObject class definition:

Code Snippet

class BaseObject<T, U>

{
abstract List<T> ReturnObject();

abstract List<U> ReturnObject();

}

Think of the maintenance headache every time the BaseObject definition changes!

Anyway, no matter how fancy we get, we can't return a generic list of base class objects and have them automatically come out the other end with their original child class type (at least not without a cast).






Re: Question regarding Generics and Inheritance

Stu

Here is a great link on this very topic - Covariance...

BTW - I stumbled across this topic, having just fallen for exactly the same trap. Some useful tips here too thanks all.