2

我有一个接口IPerson和两个类,AdventurerWorker实现它。我目前有单独ObservableCollection的冒险家和工人。我有一个方法,我希望能够将 anObservableCollection<Adventurer>和 anObservableCollection<Worker>作为参数传递,但到目前为止我还没有运气。该方法仅使用实现的属性IPerson,如果我将其声明为:

public void MyMethod(ObservableCollection<IPerson> collection)

...方法本身没有错误。但是,当我尝试传入 时,ObservableCollection<Adventurer>出现 2 个错误:

无法从“System.Collections.ObjectModel.ObservableCollection”转换为“System.Collections.ObjectModel.ObservableCollection”`

'AoW.MyMethod(System.Collections.ObjectModel.ObservableCollection)' 的最佳重载方法匹配有一些无效参数`

我可以将两个ObservableCollections 传递给同一个方法吗?如果是这样,我应该怎么做?任何建议将不胜感激。

4

2 回答 2

4

.NET 中的类不支持协变和逆变。只有接口可以。想象一下这个场景:

class Adventurer : IPerson { }
class NPC : IPerson { }

public void MyMethod(ObservableCollection<IPerson> collection)
{
    collection.Add(new NPC());
}

var collectionOfAdventurers = new ObservableCollection<Adventurer>();
MyMethod(collectionOfAdventurers);

这显然会引发一些错误,因为传入的类型是一个Adventurer集合,但该方法添加了一个NPC,但这无法在编译时验证。因此,编译器不会允许这种不安全的行为,而是要求传入的类型必须与签名中的类型完全匹配,如果您尝试传入其他任何内容,则会给出错误。

我建议更改MyMethod为:

public void MyMethod(IEnumerable<IPerson> enumerable)

或者

public void MyMethod(INotifyCollectionChanged collection)

具体取决于您需要访问的成员。

您可能还想考虑一个通用方法:

public void MyMethod<T>(ObservableCollection<T> collection) where T : IPerson
于 2013-08-17T18:53:09.983 回答
0

你不能这样做,因为

ObservableCollection<IPerson> 

本身是另一种类型(例如,您可以将 Adventurer 或 Worker 都放入其中,您不能在 Adventurer 或 Worker 的集合中这样做)

一个解决方案可能是在您的方法中允许 IPerson 的 IEnumerable,然后使用以下命令调用它:

ObservableCollection<Worker> col = ...
MyMethod(col.Cast<IPerson>());
于 2013-08-17T18:51:35.117 回答