我有一个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对象?
答案 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 ..等等),这是不行的。