[英]IList<T>, IEnumerable<T> and ObservableCollection<T>
I have two classes defined like 我有两个定义的类
public class PostleitzahlList : ObservableCollection<Postleitzahl> {
}
public class Postleitzahl : IPostleitzahl {
}
Now I have a Service-Class which contains 现在我有一个包含的服务类
PostleitzahlList _postleitzahlList;
This Serviceclass has also to implement a Property of a Service-Interface which returns _postleitzahlList
- but this Interface only knows IPostleitzahl
- it doesn't know PostleitzahlList
or Postleitzahl
. 这个Serviceclass还要实现一个返回_postleitzahlList
的Service-Interface _postleitzahlList
- 但是这个接口只知道IPostleitzahl
- 它不知道PostleitzahlList
或Postleitzahl
。 this Property should be used for Binding in WPF. 此属性应该用于WPF中的绑定。
I am trying now to declare and implement this Property. 我现在正在尝试声明并实现此属性。 I have tried 我试过了
public ObservableCollection<IPostleitzahl> PostleitzahlList {
get { return this._postleitzahlList; }
}
and 和
public IList<IPostleitzahl> PostleitzahlList {
get { return this._postleitzahlList; }
}
But both does not work. 但两者都不起作用。 The fallowing seems to work: 休假似乎有效:
public IEnumerable<IPostleitzahl> PostleitzahlList {
get { return this._postleitzahlList; }
}
I ask me now 1. why does the first and second try not working? 我现在问我1.为什么第一个和第二个尝试不起作用? 2. what is the best solution to solve this? 2.解决这个问题的最佳解决方案是什么?
The problem is with covariance. 问题在于协方差。 An ObservableCollection<Postleitzahl>
isn't an ObservableCollection<IPostleitzahl>
, and ditto with lists. ObservableCollection<Postleitzahl>
不是ObservableCollection<IPostleitzahl>
, ObservableCollection<IPostleitzahl>
与列表同上。 Here's an example of why not: 这是一个为什么不这样做的例子:
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];
... but as you can see, you're now trying to fetch a non-string reference and store it in a string variable. ...但是正如您所看到的,您现在正在尝试获取非字符串引用并将其存储在字符串变量中。 The only viable outcome would be an execution-time failure... and half the point of generics is to push error detection to compile-time . 唯一可行的结果是执行时失败......泛型的一半是将错误检测推送到编译时 。
Now IEnumerable<T>
is covariant in T
because you can't add any items via it - that makes it safe to apply that sort of conversion: 现在IEnumerable<T>
在T
是协变的 ,因为你不能通过它添加任何项目 - 这使得应用这种转换是安全的:
// There's nothing you can do to violate type safety here...
Observable<string> strings = new ObservableCollection<string>();
IEnumerable<object> objects = strings;
For more information, read up on covariance and contravariance in generics in MSDN . 有关更多信息,请阅读MSDN中泛型的协方差和逆变 。
Do you need the IPostleitzahl
interface? 您需要IPostleitzahl
界面吗? If you just exposed the properties via ObservableCollection<Postleitzahl>
or IList<Postleitzahl>
it would be fine. 如果您刚刚通过ObservableCollection<Postleitzahl>
或IList<Postleitzahl>
公开了这些属性,那就没关系了。 Alternatively, you could change your variable to be an ObservableCollection<IPostleitzahl>
and just happen to populate it by creating Postleitzahl
instances. 或者,您可以将变量更改为ObservableCollection<IPostleitzahl>
并恰好通过创建Postleitzahl
实例来填充它。
can you change PostleitzahlList to 你能改变PostleitzahlList吗?
public class PostleitzahlList : ObservableCollection<IPostleitzahl> {
}
with elementtype IPostleitzahl
instead of Postleitzahl
? 使用IPostleitzahl
而不是Postleitzahl
?
for explanation see @jon skeet answer 有关解释,请参阅@jon双向飞碟回答
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.