Unfortunately, covariance isn??™t the only problem we have to consider. There??™s
also the matter of contravariance, which is like covariance in reverse.
WHERE CONTRAVARIANCE WOULD BE USEFUL
Contravariance feels slightly less intuitive than covariance, but it does make sense.
Where covariance is about declaring that we will return a more specific object from a
method than the interface requires us to, contravariance is about being willing to
accept a more general parameter.
For instance, suppose we had an IShape interface13 that contained the Area property.
It??™s easy to write an implementation of IComparer
that sorts by area.
We??™d then like to be able to write the following code:
IComparer areaComparer = new AreaComparer();
List circles = new List();
circles.Add(new Circle(20));
circles.Add(new Circle(10));
circles.Sort(areaComparer);
That won??™t work, though, because the Sort method on List effectively takes
an IComparer. The fact that our AreaComparer can compare any shape
rather than just circles doesn??™t impress the compiler at all. It considers IComparer
and IComparer to be completely different types. Maddening, isn??™t
it? It would be nice if the Sort method had this signature instead:
void Sort(IComparer comparer) where T : S
Unfortunately, not only is that not the signature of Sort, but it can??™t be??”the constraint
is invalid, because it??™s a constraint on T instead of S.
Pages:
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226