IList <T>,IEnumerable <T>和ObservableCollection <T>

Ben*_*ual 4 .net c# collections .net-4.0 observablecollection

我有两个定义的类

public class PostleitzahlList : ObservableCollection<Postleitzahl> {
}

public class Postleitzahl : IPostleitzahl {
}
Run Code Online (Sandbox Code Playgroud)

现在我有一个包含的服务类

PostleitzahlList _postleitzahlList;
Run Code Online (Sandbox Code Playgroud)

此Serviceclass还必须实现返回的Service-Interface属性_postleitzahlList- 但此接口只知道IPostleitzahl- 它不知道PostleitzahlListPostleitzahl.此属性应该用于WPF中的绑定.

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

    public ObservableCollection<IPostleitzahl> PostleitzahlList {
        get { return this._postleitzahlList; }
    }
Run Code Online (Sandbox Code Playgroud)

    public IList<IPostleitzahl> PostleitzahlList {
        get { return this._postleitzahlList; }
    }
Run Code Online (Sandbox Code Playgroud)

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

    public IEnumerable<IPostleitzahl> PostleitzahlList {
        get { return this._postleitzahlList; }
    }
Run Code Online (Sandbox Code Playgroud)

我现在问我1.为什么第一个和第二个尝试不起作用?2.解决这个问题的最佳解决方案是什么?

Jon*_*eet 6

问题在于协方差.An 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];
Run Code Online (Sandbox Code Playgroud)

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

现在IEnumerable<T>协变T,因为你无法通过其添加的任何项目-这使得它的安全应用之类的转换:

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

有关更多信息,请阅读MSDN中泛型的协方差和逆变.

你需要IPostleitzahl界面吗?如果你刚刚通过ObservableCollection<Postleitzahl>或暴露属性,IList<Postleitzahl>它会没事的.或者,您可以将变量更改为a,ObservableCollection<IPostleitzahl>并恰好通过创建Postleitzahl实例来填充它.