Inheriting from generic List

A

Andrew McLellan

I think I must be missing something about generics, perhaps just about the
syntax. I'd like to derive a class MyList from System.Collections.Generic so
that it can only contain instance of MyItem.

No problem with

class MyList<T> : List<T>
{
}

but that requires me to create it with MyList <MyItem> myList = new
MyList<MyItem>() and I'd like to hide that bit in the list class itself so I
could call MyList myList = new MyList();

What should the constructor look like? I think it should be something like
the illegal

class MyList : List<T>
{
public MyList() : base (<T>)
{
}
}

but it obviously isn't! Is this possible or is my understanding of generics
completely wrong?

(Anyone know a good primer on this?)

Andrew
 
C

Christof Nordiek

Andrew McLellan said:
I think I must be missing something about generics, perhaps just about the
syntax. I'd like to derive a class MyList from System.Collections.Generic
so that it can only contain instance of MyItem.

No problem with

class MyList<T> : List<T>
{
}

but that requires me to create it with MyList <MyItem> myList = new
MyList<MyItem>() and I'd like to hide that bit in the list class itself so
I could call MyList myList = new MyList();

What should the constructor look like? I think it should be something like
the illegal

class MyList : List<T>
{
public MyList() : base (<T>)
{
}
}

but it obviously isn't! Is this possible or is my understanding of
generics completely wrong?

(Anyone know a good primer on this?)

Andrew
You can try:
class MyList : List<MyItem>
{
public MyList()
{
}
}

Since MyList shall always contain MyItem-objects it's no generic class
itself.
 
J

Jon Skeet [C# MVP]

Andrew McLellan said:
Thank you, exactly what I was after.

But at that stage, why not just use List<MyItem> in your code? There's
no need to create a new class here, as far as I can see - unless you're
going to add extra functionality, of course.
 
M

Marcus Andrén

But at that stage, why not just use List<MyItem> in your code? There's
no need to create a new class here, as far as I can see - unless you're
going to add extra functionality, of course.

Extending or being able to add extensions in the future is of course a
good reason.

The other reason to do it is to specify that the object has a specific
purpose. This is a classic case of Strong vs Weak typing. The
advantage with the subclass is that you attach stronger typing
information to the object. The disadvantage is that you loose some
flexibility.
 
G

Guest

Marcus Andrén said:
Extending or being able to add extensions in the future is of course a
good reason.

then should you derive from every non-sealed class in the framework before
you use it, in case in the future you might want to extend it? it is a
reason, good or not is debatable in my opinion.
 
M

Marcus Andrén

then should you derive from every non-sealed class in the framework before
you use it, in case in the future you might want to extend it? it is a
reason, good or not is debatable in my opinion.

I agree with you here. Extending just to be prepared for the future is
not really a good reason.
List<T> is already strongly typed. you can't put anything that's not T into
the List once T is defined.

class Log : List<string> {}

public void AttachLog(Log log) {}

List<string> log = new List<string>();
AttachLog(log);

This will not compile since AttachLog expects an object of type Log
and not any random List<string>. This is because Log is more strongly
defined than List<string> even though there is no functional
difference between the two classes.

In most cases I myself wouldn't bother doing it since the improvements
are minimal, although the same can be said about the disadvantages.

I actually have only used it once with generics. I was using a
Dictionary<string,string> to store options and it was being used a lot
so I created an Options class simply because it looked nicer with the
methods taking an Options parameter instead of a
Dictionary<string,string> parameter.
 
M

Michael S

My 0010 cents.

Inheritance is seldom The Good Thing. Especially in the example below. The
Log class seem to be very specific and would be better of being a simple
class derived from Object wrapping a generic list.

What I mostly dislike with inheriting from List<T> is that you get a lot of
methods that doesn't set well in context. Like Reverse() and Sort() and
stuff like that.

Happy Coding
- Michael S
 
A

amaca

But at that stage said:
no need to create a new class here, as far as I can see - unless you're
going to add extra functionality, of course.

I am indeed going to add extra functionality. This isn't necessarily how I
will end up doing it, but I am still trying to understand the C# way of
doing things, which means writing the code the way I think it shouldn't be
written and then seeing why I don't want to do it that way after all!

Andrew
 
J

Jon Skeet [C# MVP]

Is the functionality limited to MyItem though? If not, it would be
worth deriving from List<T> but keeping the implementation generic, and
allowing clients to then do SuperDuperList<MyItem> or
SuperDuperList<MyOtherItem>.

Jon
 
A

amaca

Is the functionality limited to MyItem though?

Some of it is, some of it isn't, so I'll keep the genericity for one level,
then put a class on top with the specific functionality.

Thanks all for the help.

Andrew
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top