Information Technology Reference
In-Depth Information
return either the type parameter, or an interface on the type parameter
that is also covariant.
However, the method that replaces the first item in the list will be invari-
ant when using generics:
public static void
InvariantGeneric(
IList
<
CelestialBody
> baseItems)
{
baseItems[
0
] =
new
Asteroid
{ Name =
"Hygiea"
, Mass =
8.85e19
};
}
Because IList<T> is neither decorated with the
in
or
out
modifier on T,
you must use the exact type match.
Of course, you can create Contravariant generic interfaces and delegates as
well. Substitute the
in
modifier for the
out
modifier. That instructs the
compiler that the type parameter may only appear in input positions. The
.NET Framework has added the
in
modifier to the IComparable<T>
interface:
public interface
IComparable
<
in
T>
{
int
CompareTo(T other);
}
That means you could make CelestialBody implement IComparable<T>,
using an object's mass. It would compare two Planets, a Planet and a
Moon, a Moon and an Asteroid, or any other combination. By comparing
the mass of the objects, that's a valid comparison.
Yo u ' l l n o t i c e t h a t I E q u a t a b l e < T > i s i n v a r i a n t . B y d e fi n i t i o n , a P l a n e t c a n -
not be equal to a Moon. They are different types, so it makes no sense. It
is necessary, if not sufficient, for two objects to be of the same type if they
are equal (see Item 6).
Ty p e p a r a m e te r s t h a t a re co n t r av a r i a n t c a n o n l y a p p e a r a s m e t h o d p a r a m -
eters, and some locations in delegate parameters.
By now, you've probably noticed that I've used the phrase “some locations
in delegate parameters” twice. Delegate definitions can be covariant or
contravariant as well. It's usually pretty simple: Method parameters are