我该如何为一个派生类调用一个方法?

3

简述

我想调用一个方法,该方法接受ObservableCollection<Base>类型的参数,但我想使用ObservableCollection<Derived>来调用它。它显示无法在两者之间进行转换。

详细描述

我想调用一个WPF窗口,在其中有一个将绑定到ObservableCollection的ListBox。我希望该窗口显示一些基本信息,这些信息对于两个不同的类都是共同的。这些类是Derived1Derived2,它们都基于一个BaseClass。如果类型只是BaseClass,我可以调用该方法,但我想通过列表传递参数。

因此,我有两个集合:

ObservableCollection<Derived1> A;
ObservableCollection<Derived2> B;

我希望能够调用像下面这样的方法,使用上述两个集合,这样我就不需要重复代码。

public void InitialiseWindow(ref ObservableCollection<BaseClass> List)
{
    this.List=List;
}

但它会抛出一个错误:

cannot convert from 'ref System.Collections.ObjectModel.ObservableCollection<Derived1>' to 'ref System.Collections.ObjectModel.ObservableCollection<Base>'

我在这里

有没有更好的方法将集合绑定,使得Window中所做的更改会反映在源代码上,而不是使用ref

解决方案

我修改了Window的构造函数,将IEnumerable转换为类型为ObservableCollection的公共成员。由于窗口只会以模态窗口形式显示,因此该成员可在窗口关闭后访问。

public ObservableCollection<BaseClass> List;

public InitialiseWindow(IEnumerable<BaseClass> List)
{
    InitializeComponent();
    this.List=new ObservableCollection<BaseClass>(List);
}

1
+1 - 好问题,精选细节。将来请不要添加“感谢备注”(应该点赞/采纳),也不要签名(应该编辑您的用户名)。 - Alexei Levenkov
2个回答

2

如果你仅为了绑定目的而暴露它,传递一个IEnumerable<BaseClass>引用就足够了。数据绑定系统会自动检查实际实例是否实现了INotifyCollectionChanged,因此不需要将绑定属性明确地类型化为ObservableCollection


谢谢,但是能否修改集合呢?换句话说,添加和删除项目。 - Brownish Monster
@Brownish,如果您需要修改集合(因此它不仅仅用于绑定),则一种选择是提供接口或回调来执行必要的修改。然而,这里的棘手之处在于,现在使用该集合的类需要知道仅添加派生实例,因此您可能需要考虑如何公开此内容。 - Dan Bryant
谢谢你的帮助。我按照上面的编辑修改了代码。我感觉这可能不是最好的解决方案,但可能是最简单的。我也认为我将学习回调和接口,以便能够理解它们,然后在未来实现它们。 - Brownish Monster

1

类型各不相同,对于 ref 类型必须完全匹配。

在某些情况下,您可以以类似的方式使用派生类 - 可以阅读 C#模板的协变/逆变。也就是说,您可以这样做

IEnumerable<Object> objects = new List<String>();

因为IEnumerable将其参数定义为out

 public interface IEnumerable<out T> : IEnumerable

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接