Reputation: 27733
Duplicate
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
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
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
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
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
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
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
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