When you call a method, you can supply
arguments that have more specific types than the parameters of that method. This
is ordinary polymorphic behavior. For exactly the same reason, a delegate can
have more specific parameter types than its method target. This is called
contravariance.
Example
delegate void Method1(string _var);
class Temp
{
static void Main()
{
Method1 M1 = new Method1(TempMethod);
M1("abc");
}
static void TempMethod(object str)
{
Console.WriteLine(str); // abc
}
}
If you call a method, you may get back a type that is more specific than what
you asked for. This is ordinary polymorphic behavior. For exactly the same
reason, the return type of a delegate can be less specific than the return type
of its target method. This is called covariance.
Example
delegate object Method2();
class Temp
{
static void Main()
{
Method2 _method2 = new Method2(GetVal);
object res = _method2();
Console.WriteLine(res); // abc
}
static string GetVal() { return "abc"; }
}
Conclusion
Contravariance is Method parameter compatibility (ie. arguments in method
signature) covariance is Method Return type compatibility (ie. return type in
method signature).

Join the conversation! Your thoughts help the community grow.