I have a book that explains contravariance/covariance as follows :
- a delegate can have more specific parameter types than its method target. This is called contravariance
- the return type of a delegate can be less specific than the return type of its target method. This is called covariance
And, this is an example.
using System;
delegate void StringAction(string s);
delegate object ObjectRetriever();
class Test
{
static void Main()
{
StringAction sa = new StringAction(ActionObject);
sa("hello");
ObjectRetriever o = new ObjectRetriever(RetrieveString);
object result = o();
Console.WriteLine(result);
}
static string RetrieveString() {return "hello";}
static void ActionObject(object o)
{
Console.WriteLine(o);
}
}
I thought in order to use covariance/contravariance, one needs to use new
as is shown in the example, but I seem to get the same result with sa = ActionObject
and o = RetrieveString
. (I tested with Mono).
new
to explain covariance/contravariance?object x = Everything inherit from object
? Where is this weird name come from? What's the usage for it?Covariance means that a method can return a type that is derived from the delegate's return type. Contra-variance means that a method can take a parameter that is a base of the delegate's parameter type.
Covariance can be translated as "different in the same direction," or with-different, whereas contravariance means "different in the opposite direction," or against-different. Covariant and contravariant types are not the same, but there is a correlation between them. The names imply the direction of the correlation.
You can also assign an array of objects of a more derived type to an array of objects of a base type. This is known as array covariance. It's allowed as long as the type of the source array elements is implicitly convertible to the type of the target array elements.
I have a book that explains contravariance/covariance as follows ...
That is not a very good explanation of variance. It is left completely unclear precisely what it is that is called "covariance" and "contravariance".
The thing that actually is variant is never mentioned. The thing that is contravariant is the mapping from a type to a delegate with a parameter of that type. Contravariance is a property of mappings and relationships.
Try reading this and see if you understand it any better:
http://blogs.msdn.com/b/ericlippert/archive/2007/10/19/covariance-and-contravariance-in-c-part-three-member-group-conversion-variance.aspx
I thought in order to use covariance/contravariance, one need to use new as is shown in the example, but I seem to get the same result ...
Ever since C# 2.0 you can say either "d = M" or "d = new D(M)" -- the compiler simply recognizes them as two different ways to write the same thing.
why the writer uses new to explain covariance/contravariance?
I don't know.
What's the theory behind the covariance/contravariance idea?
The theory is that if you have an ordering relationship -- that is, X is bigger than Y if it is legal to say X x = (Y)y -- and you have a mapping that preserves the ordering relationship, then the mapping is covariant. If it reverses the ordering relationship, it is contravariant.
For example, suppose Animal is a bigger type than Giraffe. So you can assign an object of type Giraffe to a variable of type Animal. Animal > Giraffe.
Now make a mapping from a type T to a method M-that-takes-a-T and to a delegate type D-that-takes-a-T.
You can assign a method M-that-takes-an-Animal to a variable of type D-that-takes-a-Giraffe. D(Giraffe) > M(Animal) but Animal > Giraffe. The relationship is reversed; the mapping is contravariant.
Is it just a fancy name describing object x = Everything inherit from object?
No. It is related to that concept because object is a larger type than almost every other type. But what is actually variant is a mapping that preserves or reverses a size relationship.
Try reading this and see if it helps.
http://blogs.msdn.com/b/ericlippert/archive/2009/11/30/what-s-the-difference-between-covariance-and-assignment-compatibility.aspx
Where is this weird name come from?
Category theory.
The best info describing covariance/contravariance in the C# I've ever seen is series of blog posts by Eric Lippert here. See starting from the bottom of the list, eleven-parts series.
It is somewhat hard to read sometimes. But it explains everything you could ask in the beginning. :)
It was written prior to actual C# 4.0 implementation, so some discussion of the syntax is obsolete, but everything else seems to be implemented just as described.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With