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
. this Property should be used for Binding in 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? 2. what is the best solution to solve this?
The problem is with covariance. An ObservableCollection<Postleitzahl>
isn't an ObservableCollection<IPostleitzahl>
, and ditto with lists. 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:
// 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 .
Do you need the IPostleitzahl
interface? If you just exposed the properties via ObservableCollection<Postleitzahl>
or IList<Postleitzahl>
it would be fine. Alternatively, you could change your variable to be an ObservableCollection<IPostleitzahl>
and just happen to populate it by creating Postleitzahl
instances.
can you change PostleitzahlList to
public class PostleitzahlList : ObservableCollection<IPostleitzahl> {
}
with elementtype IPostleitzahl
instead of Postleitzahl
?
for explanation see @jon skeet answer
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.