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