Featured post
c# - Invalid Argument - Interfaces inherited, as works, implicit casting does not. What gives? -
i have function has signature of
update(ienumberable<inotifypropertychanging> things) and class
doohickey : inotifypropertychanging, inotifypropertychanging{} when try do
list<doohickey> doohickeys = new list<doohickey>(); update(doohickeys); an exception gets thrown stating:
cannot convert 'system.collections.generic.list<doohickey>' 'system.collections.generic.ienumerable<system.componentmodel.inotifypropertychanging>' what gives? doohickey inherits inotifypropertychanging interface , list inherits ienumerable interface! how come passing object , expecting cast down doesn't?
i've included references inotifypropertychanging signify doohickey linq-to-sql class; in case bit of context matters.
this won't work because there no implicit conversion between list<doohickey> , ienumerable<notifypropertychanging>. need call:
update(doohickeys.cast<inotifypropertychanging>()); the reason behind type safety. in c#4, co-/contravariance added language, helps making these type of conversions valid. there limitations though, since type involved needs declared co-/contravariant, , applies interfaces , delegates.
the reason why can't implicitly convert list<t> list<tbase> is, make code valid:
list<t> values = new list<t>(); // add values... list<tbase> bases = values; bases.add(new tbase()); // woops. broke type safety adding tbase list of t's now, if tried when values of type ienumerable<t>, valid in c#4. because can get values out of ienumerable<t>, don't need worry lesser types being added. therefore ienumerable<t> covariant, , declared as:
ienumerable<out t> where out means "covariant". (the keywords best way remember way values may go in variant type.
co-/contravariance rather large subject, but article job of explaining important parts. , if want learn more, eric lippert has 11-part blog post series feature. eric 1 of language designers.
- Get link
- X
- Other Apps
Comments
Post a Comment