score:3

Accepted answer

this won't work because there is no implicit conversion between list<doohickey> and ienumerable<notifypropertychanging>. you need to call:

update(doohickeys.cast<inotifypropertychanging>());

the reason behind this is type safety. in c#4, co-/contravariance was added to the language, which generally helps making these type of conversions valid. there are some limitations though, since the type involved needs to be declared co-/contravariant, and it only applies to interfaces and delegates.

the reason why you can't implicitly convert list<t> to list<tbase> is, that it would make this code valid:

list<t> values = new list<t>();
// add some values...
list<tbase> bases = values;
bases.add(new tbase());  // woops. we broke type safety by adding a tbase to a list of t's

now, if you tried to do this when values was of type ienumerable<t>, it would be valid in c#4. this is because you can only get values out of ienumerable<t>, so we don't need to worry about lesser types being added. therefore ienumerable<t> is covariant, and is declared as:

ienumerable<out t>

where out means "covariant". (the keywords is actually the best way to remember which way values may go in a variant type.

co-/contravariance is a rather large subject, but this article does a good job of explaining the most important parts. and if you want to learn more, eric lippert has an 11-part blog post series about the feature. eric is one of the language designers.


Related Query

More Query from same tag