downwitch
downwitch

Reputation: 1372

Why derive a List<T> class just to restate an indexer?

I keep seeing List derived classes that look something like this

class MyClassList : List<MyClass>
{
    public MyClass this[int index]
    {
        get { return (MyClass)base[index]; }
    }
}

What is the point of this inheritance? It looks like it just restates the casting of the member. I could understand other types of indexer, but this is just a restatement of the default List indexer, and provokes a Visual Studio warning RE: hiding of the base indexer. Is this the right or wrong thing to do, and why?

Upvotes: 4

Views: 585

Answers (7)

supercat
supercat

Reputation: 81247

My guess would be that the code was trying to behave as a read-only List. One would be unable to write to an item of a variable of type MyClassList<T> by index, though one would be able to cast it back to List<T> and write a variable that way. There are times when it makes sense to have a variable whose type has limited abilities, hold an object whose actual capabilities are much greater. The proper way to do that, though, is generally with interfaces, a prime example being IEnumerable<T>. If List<T> is passed to a routine which accepts a parameter of type IEnumerable<T>, the routine could cast its parameter back to a List<T> and use members like Add(), Remove(), etc. but must routines which accept a parameter of type IEnumerable<T> won't try to use it as anything else.

A major problem with the style of code shown by the original poster is that the more 'powerful' direction is the base, rather than the derived type. Because List<T> derives from IEnumerable<T>, that means that all instances of List<T> can be enumerated, but not only some enumerable things have the extra capabilities in List<T>. By contrast, as your class is implemented, every MyClassList<T> can be read and written, but only some instances of List<T> can be used as a MyClassList<T>.

Upvotes: 0

Thomas Levesque
Thomas Levesque

Reputation: 292625

I think it is supposed to hide the set accessor of the base class, to make it look like the indexer is read-only. But it's useless, because it's very easy to work around:

MyClassList list = ...

((List<MyClass>)list)[index] = value;

Anyway, the List<T> class isn't designed for inheritance. If you need to create a specialized collection, inherit from Collection<T> instead.

Upvotes: 1

Jon Skeet
Jon Skeet

Reputation: 1503040

Perhaps it's a very poor attempt to prevent the overwriting of values via the indexer?

MyClassList x = new MyClassList();
x.Add(new MyClass());
x[0] = new MyClass(); // Error!

Of course, it doesn't stop this:

List<MyClass> x = new MyClassList();
x.Add(new MyClass());
x[0] = new MyClass(); // No problem here...

Basically, it's a bad idea. Poor code abounds, unfortunately - don't infer usefulness from mere existence :(

Upvotes: 5

Tigran
Tigran

Reputation: 62265

this is, basically, a try to make correctly override of [] access to List, to implement some custom element access logic.

Worth mantioned that the code provided is not good, if not just dangerous. If you want to do somethign tricky with list do not override (or tend to do so) [], but implement some custom method for that purpose.

Upvotes: 0

Erix
Erix

Reputation: 7105

I don't see any usefulness to doing this. Also, the cast is unnecessary.

Upvotes: 1

StriplingWarrior
StriplingWarrior

Reputation: 156654

There is no good reason for this. It hides the base indexer instead of overriding it, which could be dangerous, and it doesn't have any effect at all.

In most cases, it's best just to use a List<MyClass> directly. There's no need to create a special class for this if you're not planning to extend List<>'s functionality at all.

Upvotes: 2

krystan honour
krystan honour

Reputation: 6803

I've seen this type of stuff before where people want to serialise it out as another type, for now if thats the only code in there and its not required to be of type MyClassList for other reasons, its totally pointless.

Upvotes: 0

Related Questions