Prev | Current Page 210 | Next

Jon Skeet

"C# in Depth: What you need to master C# 2 and 3"

6.1 Lack of covariance and contravariance
In section 2.3.2, we looked at the covariance of arrays??”the fact that an array of a reference
type can be viewed as an array of its base type, or an array of any of the interfaces
it implements. Generics don??™t support this??”they are invariant. This is for the sake of
type safety, as we??™ll see, but it can be annoying.
WHY DON??™T GENERICS SUPPORT COVARIANCE?
Let??™s suppose we have two classes, Animal and Cat, where Cat derives from Animal. In
the code that follows, the array code (on the left) is valid C# 2; the generic code (on
the right) isn??™t:
The compiler has no problem with the second line in either case, but the first line on
the right causes the error:
error CS0029: Cannot implicitly convert type
'System.Collections.Generic.List' to
'System.Collections.Generic.List'
This was a deliberate choice on the part of the framework and language designers. The
obvious question to ask is why this is prohibited??”and the answer lies on the second
line. There is nothing about the second line that should raise any suspicion. After all,
List effectively has a method with the signature void Add(Animal value)??”
you should be able to put a Turtle into any list of animals, for instance. However, the
actual object referred to by animals is a Cat[] (in the code on the left) or a List
(on the right), both of which require that only references to instances of Cat are stored
in them.


Pages:
198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222