-5

I've been digging through several posts on this subject and could not find any suitable answer to the following problem…

can anyone tell me why this does not compile :

class MyItem {
    public int ID;
}
class MyList<T> {
    public List<T> ItemList;
}


class MyDerivedItem : MyItem {
    public string Name;
}
class MyDerivedList<MyDerivedItem> : MyList<MyDerivedItem> {
    public int GetID(int index) {
        return ItemList[index].ID; // ERROR : MyDerivedItem does not contain a definition for ID
    }
    public string GetName(int index) {
        return ItemList[index].Name; // ERROR : MyDerivedItem does not contain a definition for Name
    }
}

2 Answers2

1

You have a few issues with this, this first of which is your generic signature.

While class MyDerivedList<MyDerivedItem> : MyList<MyDerivedItem> may seem like a generic class declaration using MyDerivedItem as the type, you've really just declared a generic class that uses MyDerivedItem as the name of the generic type argument.

What you're looking for is class MyDerivedList<T> : MyList<T> where T : MyDerivedItem, which will exchange your first problem for your next one, which is that the properties of your other types are not accessible enough for this one.

class MyItem
{
    public int ID;
}
class MyList<T>
{
    public List<T> ItemList;
}

class MyDerivedItem : MyItem
{
    public string Name;
}

Okay, now the properties are accessible enough to be accessed from the MyDerivedList class, but there's one last issue to correct. int GetName(int index) should be string GetName(int index), as the Name property is a string.

This results in the following:

class MyDerivedList<T> : MyList<T> where T : MyDerivedItem
{
    int GetID(int index)
    {
        return ItemList[index].ID;
    }
    string GetName(int index)
    {
        return ItemList[index].Name; 
    }
}

Which should compile just fine.

Jonathon Chase
  • 9,396
  • 21
  • 39
0

Jonathon's answer is correct but maybe the proposed solution is not exactly what you want.

Maybe you simply want a non generic type that inherits a closed generic type:

class MyDerivedList : MyList<MyDerivedItem>

And now your code will work as expected:

 class MyDerivedList : MyList<MyDerivedItem>
 {
    int GetID(int index)
    {
        return ItemList[index].ID;
    }

    string GetName(int index)
    {
        return ItemList[index].Name; 
    }
}

Contrary to your attempt, in the code above MyDerivedItem really is the type MyDerivedItem and not a generic type parameter of the generic class MyDerivedList<>.

Confusing? Yes, that is why you should avoid naming generic type parameters with type names, it can make your head hurt; your code and the following are exactly the same:

class MyDerivedList<T> : MyList<T> 

But now the fact that T is a generic type parameter and not a concrete type is obvious.

InBetween
  • 32,319
  • 3
  • 50
  • 90