Covariance and Contravariance are the two new features introduced by C# 2.0 in which, delegate objects support the notion of covariance on their return type and contravariance on their arguments.
Covariance enables a method to be assigned to a delegate when the method's return type is a class derived from the class specified by the return type of the delegate.
Contravariance enables a method to be assigned to a delegate when a method's parameter type is a base class specified by the delagate's declaration.
Example:
Covariance enables a method to be assigned to a delegate when the method's return type is a class derived from the class specified by the return type of the delegate.
Contravariance enables a method to be assigned to a delegate when a method's parameter type is a base class specified by the delagate's declaration.
Example:
// Demonstrate
covariance and contravariance.
using System;
class ReturnX
{
public int iValue;
}
// ArgumentY is
derived from ReturnX.
class ArgumentY : ReturnX {
}
// This delegate
returns ReturnX and takes an ArgumentY argument.
delegate ReturnX
ChangeIt(ArgumentY obj);
class CoContraVariance
{
// This method returns ReturnX and has an
ReturnX parameter.
static ReturnX IncrA(ReturnX obj)
{
ReturnX oReturnX = new ReturnX();
oReturnX.iValue = obj.iValue + 1;
return oReturnX;
}
// This method returns ArgumentY and has a
ArgumentY parameter.
static ArgumentY IncrB(ArgumentY obj)
{
ArgumentY oArgumentY = new ArgumentY();
oArgumentY.iValue = obj.iValue + 1;
return oArgumentY;
}
static void Main ()
{
ArgumentY oArgumentY = new ArgumentY();
// In this case, the parameter to IncrA is
ReturnX and the parameter to ChangeIt is
// ArgumentY.
// ArgumentY.
// Because of contravariance, the following
line is OK.
ChangeIt oChangeIt = IncrA;
ReturnX oReturnX = oChangeIt(oArgumentY);
Console.WriteLine("oReturnX: " +
oReturnX.iValue);
// In the next case, the return type of
IncrB is ArgumentY and the return type of
// ChangeIt is ReturnX.
// ChangeIt is ReturnX.
// Because of covariance, the following
line is OK.
oChangeIt = IncrB;
oArgumentY = (ArgumentY)
oChangeIt(oArgumentY);
Console.WriteLine("oArgumentY: "
+ oArgumentY.iValue);
}
}
The output from the program
is shown here:
oReturnX: 1