Information Technology Reference
In-Depth Information
public class Asteroid : CelestialBody
{
// elided
}
This method treats arrays of CelestialBody objects covariantly, and does so
safely:
public static void CoVariantArray( CelestialBody [] baseItems)
{
foreach ( var thing in baseItems)
Console .WriteLine( "{0} has a mass of {1} Kg" ,
thing.Name, thing.Mass);
}
This method also treats arrays of CelestialBody objects covariantly, but it
is not safe. The assignment statement will throw an exception.
public static void UnsafeVariantArray(
CelestialBody [] baseItems)
{
baseItems[ 0 ] = new Asteroid
{ Name = "Hygiea" , Mass = 8.85e19 };
}
Yo u c a n h a v e t h e s a m e p r o b l e m s i m p l y b y a s s i g n i n g a n a r r a y o f a d e r i v e d
class to a variable that is an array of a base type:
CelestialBody [] spaceJunk = new Asteroid [ 5 ];
spaceJunk[ 0 ] = new Planet ();
Tr e a t i n g c o l l e c t i o n s a s c o v a r i a n t m e a n s t h a t w h e n t h e r e i s a n i n h e r i t a n c e
relationship between two types, you can imagine there is a similar inher-
itance relationship between arrays of those two types. This isn't a strict
definition, but it's a useful picture to keep in your mind. A Planet can be
passed to any method that expects CelestialBody. That's because Planet is
derived from CelestialBody. Similarly, you can pass a Planet[] to any
method that expects a CelestialBody[]. But, as the above example shows,
that doesn't always work the way you'd expect.
When generics were first introduced, this issue was dealt with in a rather
draconian fashion. Generics were always treated invariantly. Generic types
had to have an exact match. However, in C# 4.0, you can now decorate
 
Search WWH ::




Custom Search