2013-08-17 63 views
2

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

public void MyMethod(ObservableCollection<IPerson> collection) 

...有方法本身里面没有错误。然而,当我尝试在ObservableCollection<Adventurer>传递,我得到2个错误:

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

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

我可以通过ObservableCollection s到同一个方法吗?如果是这样,我应该怎么做呢?任何建议将不胜感激。

回答

3

类在.NET中不支持covariance and contravariance。只有接口可以。想象一下这样的场景:

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 
+0

更改到'IEnumerable的'的伎俩。谢谢你的帮助。 –

0

因为

ObservableCollection<IPerson> 

是 本身另一种类型(例如,你可以把双方的冒险家或其中的工人不能做这种方式,你不能做一个集合中冒险家或工人)

的解决办法是允许IPerson的IEnumerable的在你的方法,然后使用叫它:

ObservableCollection<Worker> col = ... 
MyMethod(col.Cast<IPerson>());