sarsnake
sarsnake

Reputation: 27733

Inheritance in C# - simple question

Duplicate

In C#, why can’t a List object be stored in a List variable

Here is my code:

public class Base
    {
        protected BindingList<SampleBase> m_samples;

        public Base() { }
    }

    public class Derived : Base
    {
        public Derived()
        {
            m_samples = new BindingList<SampleDerived>();
        }
    }

SampleDerived is derived from SampleBase

According to the inheritance logic, I should be able to do this. However, it doesn't compile - the error says that SampleBase can not be be implicitly converted to SampleDerived type. What gives?

I am using c# 2.0

Upvotes: 2

Views: 660

Answers (7)

kvb
kvb

Reputation: 55185

The people pointing you to Eric Lippert's excellent posts on variance are right, but here's a short example showing what would go wrong. I've just added a new method to the base class and I'm using another derived sample class. What would happen when the BreakDerived method is called on an instance of your original Derived class? You can't add an instance of SampleDerived2 to the BindingList<SampledDerived>.

public class Base {
    protected BindingList<SampleBase> m_samples;
    public Base() { }
    public BreakDerived() { m_samples.Add(new SampleDerived2()); }    
}

public class Derived : Base {
    public Derived() { m_samples = new BindingList<SampledDerived>(); }
}

Upvotes: 0

dahlbyk
dahlbyk

Reputation: 77620

You're trying to use covariance, which is not supported by C# 3.0 and earlier (but will be in C# 4.0). You can still add objects of type SampleDerived into m_samples, but the list's generic type will need to be SampleBase.

Edit: So Pavel is right, C# 4.0 doesn't actually help with this. It would if m_sample were defined as IBindingList<SampleBase> using (fictional) covariant interface IBindingList<out T>.

Upvotes: 4

JP Alioto
JP Alioto

Reputation: 45127

This type of generic variance is not supported in C#2 or 3. It will be supported in C#4. (See comment.) Eric Lippert has a series of blog posts on this subject that goes into enough detail to kill any unwary developer. :)

Upvotes: 0

Alex Yakunin
Alex Yakunin

Reputation: 6678

Most likely you must simply create the list instance in your base class, and freely use it in derived.

public class Base
{
    protected BindingList<SampleBase> m_samples = new BindingList<Derived>();

    public Base() { }
}

public class Derived : Base
{
    public FwdRunData()
    {
        m_samples.Add(new Derived>());
    }
}

Upvotes: 0

Babak Naffas
Babak Naffas

Reputation: 12581

Generics cannot be casted.

You can cast List<MyClass> to IList<MyClass> or even IList, but this would be illegal:

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

Upvotes: 0

Steve Gilham
Steve Gilham

Reputation: 11277

A BindingList<SampleDerived> is not a BindingList<SampleBase> -- you can add a SampleBase to the latter, but not to the former.

Upvotes: 1

drs9222
drs9222

Reputation: 4508

I can understand why you would think that but generics don't work that way. :(

BindingList<SampleDerived> does not actually derive from BindingList<SampleBase>

Upvotes: 2

Related Questions