C#中的继承 - 简单问题

时间:2009-07-24 22:54:19

标签: c# generics inheritance covariance

  

复制

     

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

这是我的代码:

public class Base
    {
        protected BindingList<SampleBase> m_samples;

        public Base() { }
    }

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

SampleDerived派生自SampleBase

根据继承逻辑,我应该能够做到这一点。但是,它没有编译 - 错误说SampleBase不能隐式转换为SampleDerived类型。是什么给了什么?

我正在使用c#2.0

7 个答案:

答案 0 :(得分:4)

您正在尝试使用协方差,C#3.0及更早版本不支持该协方差(但将在C#4.0中使用)。您仍然可以将SampleDerived类型的对象添加到m_samples,但列表的通用类型必须为SampleBase

编辑:所以Pavel是对的,C#4.0实际上并没有帮助。如果使用(虚构的)协变接口m_sampleIBindingList<SampleBase>定义为IBindingList<out T>,则会这样做。

答案 1 :(得分:2)

我可以理解为什么你会这么想,但是仿制药不会这样。 :(

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

答案 2 :(得分:1)

BindingList<SampleDerived>不是BindingList<SampleBase> - 您可以为后者添加SampleBase,但不能向前者添加。{/ p>

答案 3 :(得分:0)

无法输入泛型。

您可以将List<MyClass>投射到IList<MyClass>甚至IList,但这可能是非法的:

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

答案 4 :(得分:0)

C#2或3不支持

This type of generic variance C#4将支持它。(见评论。)Eric Lippert对此有一个series of blog posts足够详细的主题可以杀死任何不知情的开发人员。 :)

答案 5 :(得分:0)

您很可能只需在基类中创建列表实例,并在派生中自由使用它。

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

    public Base() { }
}

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

答案 6 :(得分:0)

人们指向Eric Lippert关于差异的优秀帖子是正确的,但这里有一个简短的例子,说明会出现什么问题。我刚刚给基类添加了一个新方法,我正在使用另一个派生的样本类。在原始BreakDerived类的实例上调用Derived方法时会发生什么?您无法将SampleDerived2的实例添加到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>(); }
}