ObservableCollection作为参数和接口传递

时间:2013-08-17 18:45:02

标签: c# interface observablecollection

我有一个接口IPerson和两个实现它的类AdventurerWorker。我目前为冒险家和工人分别有ObservableCollection个。我有一个方法,我希望能够将ObservableCollection<Adventurer>ObservableCollection<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)'的最佳重载方法匹配有一些无效的参数。

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

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:0)

你不能这样做,因为

ObservableCollection<IPerson> 

时  本身是另一种类型(例如,你可以把冒险家或工人放在其中,你不能在冒险家或工人的集合中做到这一点)

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

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