IList <t>,IEnumerable <t>和ObservableCollection <t> </t> </t> </t>

时间:2012-05-22 11:36:50

标签: c# .net collections .net-4.0 observablecollection

我有两个类定义为

public class PostleitzahlList : ObservableCollection<Postleitzahl> {
}

public class Postleitzahl : IPostleitzahl {
}

现在我有一个包含

的服务类
PostleitzahlList _postleitzahlList;

此Serviceclass还必须实现返回_postleitzahlList的服务接口的属性 - 但此接口仅知道IPostleitzahl - 它不知道PostleitzahlList或{{1} }。此属性应该用于WPF中的绑定。

我现在正在尝试声明并实现此属性。我试过了

Postleitzahl

    public ObservableCollection<IPostleitzahl> PostleitzahlList {
        get { return this._postleitzahlList; }
    }

但两者都不起作用。 休假似乎有效:

    public IList<IPostleitzahl> PostleitzahlList {
        get { return this._postleitzahlList; }
    }
我现在问我 1.为什么第一次和第二次尝试不起作用? 2.解决这个问题的最佳解决方案是什么?

2 个答案:

答案 0 :(得分:5)

问题在于协方差。 ObservableCollection<Postleitzahl>不是ObservableCollection<IPostleitzahl>,与列表同上。以下是为什么不这样做的例子:

ObservableCollection<string> strings = new ObservableCollection<string>();

// This is invalid, but it's what you're trying to do, effectively.
ObservableCollection<object> objects = strings;

// This would have to work... it's fine...
objects.Add(new object());

// And this should be fine too...
string x = strings[0];

...但正如您所看到的,您现在正在尝试获取非字符串引用并将其存储在字符串变量中。唯一可行的结果是执行时失败......泛型的一半是将错误检测推送到编译时

现在IEnumerable<T>T中是协变,因为您无法通过它添加任何项目 - 这样可以安全地应用这种转换:

// There's nothing you can do to violate type safety here...
Observable<string> strings = new ObservableCollection<string>();
IEnumerable<object> objects = strings;

有关详细信息,请阅读covariance and contravariance in generics in MSDN

您需要IPostleitzahl界面吗?如果您刚刚通过ObservableCollection<Postleitzahl>IList<Postleitzahl>公开了这些属性,那就没关系。或者,您可以将变量更改为ObservableCollection<IPostleitzahl>,并恰好通过创建Postleitzahl个实例来填充它。

答案 1 :(得分:0)

可以将PostleitzahlList更改为

public class PostleitzahlList : ObservableCollection<IPostleitzahl> {
}

使用元素类型IPostleitzahl而不是Postleitzahl

有关解释,请参阅@jon双向答案