将子类转换为继承的类

时间:2010-05-26 13:22:44

标签: c# visual-studio visual-studio-2008 inheritance

我有一个C#.NET 2.0项目A(类库),它有一个使用Tree对象的表单(TreeForm)。

我有一个项目B,它有一个继承Tree的类Oak。 Oak类为Tree添加了一些属性。

class Oak : ProjectA.Tree
{
   public string LeafColor;
}

类库中的TreeForm.cs是一个具有DataGrid的表单,该DataGrid数据绑定到Tree对象的BindingList。

当我尝试使用我的Oak对象引用和使用项目B中的TreeForm时,它正在寻找Tree类型的对象。

// in project B here.
BindingList<Oak> oaklist = BindingList<Oak>();

private void show_treeform_button_Click(object sender, EventArgs e)
{
   ProjectA.TreeForm tree_form = new ProjectA.TreeForm(oaklist); // this line gives error
   tree_form.Show();
}

我已经尝试将Oak对象转换为Tree,但是我收到错误“无法将类型Oak转换为Tree”。如果我只使用项目B中的对象作为Tree对象,它可以正常工作。

如何在项目A的TreeForm中使用我的Oak对象?

5 个答案:

答案 0 :(得分:3)

您需要发布一个简短但完整的代码示例以获得任何有意义的帮助。但是让我冒昧地猜测。

第二个项目(B)是否引用了第一个项目(A)?您必须确保类型Tree在两个实例中实际上都是相同的树类型。在你描述的例子中 - 听起来像项目A实际上有一个对项目B的引用 - 在这种情况下,B如何知道Tree

如果您在两个项目中都声明了Tree类 - 它与Tree类不同。

一个项目必须引用另一个项目的Tree类,以便这种安排按照您期望的方式工作。

组织此类项目的一般方法是将共享类移动到第三个类库程序集,并在项目A和项目B中引用该程序集。然后,您可以继承和使用类库正确公开的类型。

编辑:现在你发布了一些代码,可以给你一个更准确的回复。看起来你要做的就是传递{{的通用列表1}}一个期望Oak的通用列表的方法。在.NET 4支持通用覆盖(在接口类型BTW上)之前,您无法做到这一点。

在4#之前的C#版本中,你无法做到:

Tree

仅仅因为List<Oak> oaklist = new List<Oak>(); List<Tree> treeList = oaklist; // illegal 继承Oak并不意味着Tree继承List<Oak>

您可以在Eric Lippert的博客上阅读有关generic variance的更多信息。

因此,在您的情况下,如果您想将Oaks列表传递到List<Tree>,则需要将其作为TreeForm()列表传递。假设您不想更改集合的类型,您可以只实例化一个适当的副本:

Tree

答案 1 :(得分:2)

问题是在.NET 4.0之前,generics did not support covariance - 您的TreeForm类需要BindingList<Tree>,而不是BindingList<Oak>。认为我们可以将派生的绑定列表替换为基础是一个常见的错误,但我们不能。

幸运的是,我们不需要,因为BindingList<Tree>可以包含Oak个实例。解决方案是声明你的变量:

BindingList<Tree> oakList = new BindingList<Tree>();
// Add Oaks, pass to TreeForm

(关于大脑弯曲的细节,请参阅Eric Lippert的series of articles on variance in C#。)

答案 2 :(得分:1)

您是否要将列表声明为BindingList<Tree>,然后将Oak个实例添加到其中,然后将BindingList<Tree>个对象传递给A的TreeForm构造函数。在所有项目A都无法处理Oak对象之后,因为它对它们一无所知,它们在项目B中定义。

答案 3 :(得分:0)

您似乎只在项目B中继承了Tree中的Oak,因此Project A不知道Oak是从Tree继承的。 您应该使用类库,并且两个项目都有一个引用。

答案 4 :(得分:0)

如果我没有误会你试图从ProjA中访问继承自Tree(ProjA)的Oak(来自ProjB)?

如果是这样,你最终会得到一个循环引用(A> B> A&gt; B&gt; A ..等等),这是不行的。