19

I have abstract class:

public abstract class MyClass
{
    public abstract string nazwa
    {
        get;
    }
}

And two classes which inherit from MyClass:

public class MyClass1 : MyClass
{
    public override string nazwa
    {
        get { return "aaa"; }
    }
}

public class MyClass2 : MyClass
{
    public override string nazwa
    {
        get { return "bbb"; }
    }
}

In another class I create List:

List<MyClass> myList;

Now I want to create

myList = new List<MyClass1>;

The compiler show an error:

Cannot implicitly convert type 'System.Collections.Generic.List<Program.MyClass1>' to 'System.Collections.Generic.List<Program.MyClass>'

I must be some easy way to convert it... I cannot find anything useful

Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
Pieniadz
  • 653
  • 3
  • 9
  • 22
  • While an implicit conversion might not work, you can try an explicit conversion. By casting for example: http://msdn.microsoft.com/en-us/library/ms173105(v=vs.80).aspx – Simeon G Sep 19 '11 at 17:48
  • What's the use of reusing the simple reference var `myList` ? Just create a new variable. – H H Sep 19 '11 at 17:50
  • Why do you want to do this? Is there a particular way that you want to use the class that could not be accomplished through instantiating it as new List()? – Maciej Sep 19 '11 at 17:58
  • Because MyClass1 and MyClass2 in my program have different properties. And it depends from user choice, which one is being used. And in some funcions I want to use properties which are in both classes. it is complicated ;P – Pieniadz Sep 19 '11 at 18:30

3 Answers3

16

You can create the list as the base type:

List<MyClass> myList = new List<MyClass>();

Which you can then add derived items to:

myList.Add(new MyClass2());
Joel Beckham
  • 18,254
  • 3
  • 35
  • 58
  • You are right, that I don't need to create List, to add there items of MyClass2. It works, thanks. :) – Pieniadz Sep 20 '11 at 11:43
  • Thank you so much @Joel Beckham! It works like a charm! I have been looking for a solution to this everywhere, thanks again! – user2768479 Apr 02 '20 at 09:46
13

It is not safe to convert a List<Derived> to a List<Base>.

What do you expect to happen if you write

List<MyClass1> derivedList = ...
List<MyClass> baseList = derivedList;
baseList.Add(new MyClass2());    //Boom!

You're asking for covariance; covariance is only possible with read-only interfaces.
Thus, IEnumerable<Derived> is convertible to IEnumerable<Base>.

SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
3

You must have a base class list, and later you can use Linq to get the MyClas1 item list when you need it.

 List<MyClass> BaseList = new ...

 BaseList.FillWithItems();

 List<MyClass1> DerivedList = BaseList.OfType<MyClass1>().ToList();
Blau
  • 5,742
  • 1
  • 18
  • 27