Can anyone explain me, the concept of covariance and contravariance in programming languages theory?
Covariance is pretty simple and best thought of from the perspective of some collection class List
. We can parameterize the List
class with some type parameter T
. That is, our list contains elements of type T
for some T
. List would be covariant if
S is a subtype of T iff List[S] is a subtype of List[T]
(Where I'm using the mathemtical definition iff to mean if and only if.)
That is, a List[Apple]
is a List[Fruit]
. If there is some routine which accepts a List[Fruit]
as a parameter, and I have a List[Apple]
, then I can pass this in as a valid parameter.
def something(l: List[Fruit]) {
l.add(new Pear())
}
If our collection class List
is mutable, then covariance makes no sense because we might assume that our routine could add some other fruit (which was not an apple) as above. Hence we should only like immutable collection classes to be covariant!
Here are my articles on how we have added new variance features to C# 4.0. Start from the bottom.
http://blogs.msdn.com/ericlippert/archive/tags/Covariance+and+Contravariance/default.aspx
Bart De Smet has a great blog entry about covariance & contravariance here.
For added convenience, here's an ordered list of links to all of Eric Lippert's articles on variance:
- Covariance and Contravariance in C#, Part One
- Covariance and Contravariance in C#, Part Two: Array Covariance
- Covariance and Contravariance in C#, Part Three: Method Group Conversion Variance
- Covariance and Contravariance in C#, Part Four: Real Delegate Variance
- Covariance and Contravariance In C#, Part Five: Higher Order Functions Hurt My Brain
- Covariance and Contravariance in C#, Part Six: Interface Variance
- Covariance and Contravariance in C# Part Seven: Why Do We Need A Syntax At All?
- Covariance and Contravariance in C#, Part Eight: Syntax Options
- Covariance and Contravariance in C#, Part Nine: Breaking Changes
- Covariance and Contravariance in C#, Part Ten: Dealing With Ambiguity