David Williams
David Williams

Reputation: 355

Creating an IList<T> of Item<U>?

So I have an object, lets say Item<U>. I want to create a(n) (I)List<T> containing a collection of these items. The problem that I am running into is that the collection of Item<U> can have any number of different types for U in them.

What I can not figure out is the signature to use for the IList. I tryed IList<Item<T>>, but because I do not (in the class where the IList is to be used) have a defination of T (which as I said varys anyhow) I can not use this signature. What is the best way to approach this requirement?

Upvotes: 2

Views: 2177

Answers (6)

Grzenio
Grzenio

Reputation: 36649

Its a bit of a pain in .Net 3, because all the Item for different U are treated as independent types. To make it work you have to manually introduce an interface for this type:

interface IItem{}

class Item<U>:IItem {...}

and now you can:

IList<IItem> list = new IList<IItem>();
list.Add(new Item<string>());
list.Add(new Item<int>());

Alternatively you could stick to the non-generic list.

Upvotes: 1

John Feminella
John Feminella

Reputation: 311526

An IList is meant to hold a single type. To decide if something is a "single type" or not, you have to expand all the type parameters. Taking your example of an IList<Item<T>>, the T would have to be one and only one thing for a particular instance.

For example, you can pick Animal for T and then proceed to put Dog, Cat, and Bear instances in the IList. But you can't put arbitrary types there; they have to be able to be converted to the type you specify for T. And if your types are and not related in this way, you don't have any choice except to have a non-generic interface for your list. You could also consider defining an interface type for T that all your eligible items can conform to.

Once you've decided what T will be, you can then make your method generic:

public void PrintItems<T>(IList<Item<T>> list)
{
  // ...
}

Upvotes: 2

Lasse V. Karlsen
Lasse V. Karlsen

Reputation: 391336

You need to add a non-generic interface to your Item<U> and make the collection out of those interfaces.

There is no way you can create a collection of IList<Item<T>> where T is some base type for a lot of different object types you want to place into the same list. This is co(ntra)-variance in place which specifically prohibits this.

So you need to instead add something common, that isn't generic, and make the list out of that. For instance, you might make Item<T> implement IItem, and create IList<IItem> instead.

That's the best you can do.

Upvotes: 5

AakashM
AakashM

Reputation: 63338

I think you just want an IList<Item<U>>. The key is that the T in the name of the generic type IList<T> is just a placeholder - it doesn't have any special meaning. You want a list of Item<U>s, so just make one.

Now, this will of course mean that the method / class that contains this IList will itself be generic in U, but that seems to be dictated by the terms of your question.

Upvotes: 0

Daniel A. White
Daniel A. White

Reputation: 190945

You could try this

class Item<U>
{
   ...
}


class Item : Item<object> {
   ...
}

....
IList<Item> itemList;

Upvotes: 0

Klaus Byskov Pedersen
Klaus Byskov Pedersen

Reputation: 120937

You can make your method generic, like:

public void DoSomethingWithTheList<T>(IList<Item<T>> theList)
{
    //Do that something
}

Upvotes: 1

Related Questions