0

Is it possible to inherit a List of base objects as List of derived objects? Don't know how to explain it better. Hope this example makes it clear:

public abstract class MyBase
{ }

public class MyConcrete: MyBase
{ }

public abstract class MyBases: IList<MyBase>
{
    internal abstract List<MyBase> Items { get; set; }
    public MyBase this[int index] { get => ((IList<MyBase>)Items)[index]; set => ((IList<MyBase>)Items)[index] = value; }

    // other implementations of IList...
}

public class MyConcretes: MyBases
{
    //Possible:
    internal override List<MyBase> Items { get; set; }

    // Needed
    internal override List<MyConcrete> Items { get; set; }
}
marsh-wiggle
  • 2,508
  • 3
  • 35
  • 52
  • The variance rules of C# will not let you do this with `List` because `T` appears as both an input and an output. You may be able to get something to work if you use `IReadOnlyList` instead, which (I believe) is covariant on `T`. – Mike Strobel Mar 28 '19 at 18:11
  • @MikeStrobel So the only possibility I have is to use the "MyBase" and cast it every time? – marsh-wiggle Mar 28 '19 at 18:13
  • you can make your class generic to handle this. as a side note you should not inherit from IList, its rare that you actually need to extend the functionality of a list, you probably just want to keep a list as an internal member – johnny 5 Mar 28 '19 at 18:16
  • If someone finds a better wording for the title, then please change. – marsh-wiggle Mar 28 '19 at 18:49
  • @MikeStrobel: That's correct; it is covariant. – Eric Lippert Mar 28 '19 at 19:09
  • @MikeStrobel this may be a stupid question: The answer (https://stackoverflow.com/a/55404316/1574221) works. Will I run in any problems using it? – marsh-wiggle Mar 28 '19 at 19:22
  • Possible duplicate of [C# List: why you cannot do \`List foo = new List();\`](https://stackoverflow.com/questions/1228173/c-sharp-listinterface-why-you-cannot-do-listifoo-foo-new-listbar) – Brian Mar 28 '19 at 21:08

1 Answers1

1

You can use template class.

public abstract class MyBases<T> : IList<T>
{
    internal abstract List<T> Items { get; set; }
    public MyBase this[int index] { get => ((IList<MyBase>)Items)[index]; set => ((IList<MyBase>)Items)[index] = value; }

    // other implementations of IList...
}

public class MyConcretes : MyBases<MyConcrete>
{
    internal override List<MyConcrete> Items { get; set; }
}
Lana
  • 1,024
  • 1
  • 7
  • 14