2010-05-26 153 views
4

我有一个C#.NET 2.0项目A(类库),它具有使用Tree对象的窗体(TreeForm)。将子类转换为继承类

我有一个项目B,它拥有继承Tree的类Oak。 Oak类将一些属性添加到树中。

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

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

当我尝试引用和使用项目B中的TreeForm和我的Oak对象时,它正在寻找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(); 
} 

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

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

+2

向我们展示您的代码,请 – prostynick 2010-05-26 13:25:21

+0

什么,你现在要做的正常工作,所以我们需要看到(至少)Oak的声明和声明Tree变量的TreeForm的相关部分。另外,Tree类定义在哪里 - 在你正在讨论的两个程序集之一还是第三个程序集中? – 2010-05-26 13:27:15

+2

您是否在这两个项目中声明了树类? – volody 2010-05-26 13:29:19

回答

3

您将需要发布简短但完整的代码示例以获得任何有意义的帮助。但让我在这里冒险猜测。

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

如果在两个项目中声明了Tree类 - 它不是同一个Tree类。

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

组织这样的项目的一般方法,是将共享类移动到第三类库组件,和参考该组件在这两个项目A和项目B.然后可以继承和消耗由露出的类型类库正确。

编辑:所以,现在你已经发布了一些代码,它可以给你一个更准确的响应。它看起来像你想要做的是将Oak的通用列表传递给期望Tree的通用列表的方法。这不是在.NET 4之前可以做的事情,它支持泛型重要性(在接口类型BTW上)。

在之前4的C#版本中,你不能做:

List<Oak> oaklist = new List<Oak>(); 
List<Tree> treeList = oaklist; // illegal 

只是因为Oak继承Tree并不意味着List<Oak>继承List<Tree>

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

所以在你的情况下,如果你想通过一个奥克列表TreeForm()你需要通过它作为Tree列表。假设你不想改变集合类型,你可以实例化一个合适的副本:

ProjectA.TreeForm tree_form = 
     new ProjectA.TreeForm(new List<Tree>(oaklist.Cast<Tree>()));  
+0

添加了一些代码 - 项目A是一个类库,它使用项目A中的Tree对象。 – Dave 2010-05-26 14:04:32

0

看起来你只是在项目B中继承了树的橡树,所以项目A并不知道橡树是从树继承的。 你应该使用一个类库,两个项目都有一个参考。

+0

应该更清楚 - 项目A是一个类库。查看更新。 – Dave 2010-05-26 14:05:13

0

如果我不是错误地试图访问从ProjA中的树(ProjA)继承的橡树(来自ProjB)?

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

+0

VS IDE会将此显示为错误 – volody 2010-05-26 13:36:25

1

难道你想声明列表中BindingList<Tree>然后添加Oak实例,然后通过BindingList<Tree>反对给A的TreeForm构造函数。毕竟项目A不能与Oak对象处理,因为它不知道他们什么,他们在项目B.定义

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 

(对于脑弯曲的详情,请参阅埃里克利珀的series of articles on variance in C#