Search code examples
c#genericsderived-class

C# Generic and Derivation


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
    }
}

Solution

  • 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.