Introduction
In this article, we will look into Covariance and Contravariance in Delegates using C#. We know that delegate is a type-safe function pointer referencing a method. Any method matching the delegate signature can be assigned to the delegate and can be called a method. Once a delegate is assigned to a method, it behaves exactly as a method. Delegates provide the below benefits.
- We can pass methods as parameters to other methods.
- To define callback methods.
- Multiple methods can be called with a single delegate.
C# provides a degree of flexibility when matching a delegate type with the method signature. It doesn't require matching delegate signatures exactly. Covariance allows us to have a more derived type as a return type than specified in the delegate declaration. Similar way, Contravariance allows us to have less derived type as parameter type than specified in the delegate. Let's see it with an example.
What is Covariance in Delegates?
Covariance, we are able to call a method that has return type[child] derived from return type[parent] in delegate declaration.
Example
using System;
class Parent
{
}
class Child : Parent
{
}
class Program
{
public delegate Parent CovarianceHandler();
public static Parent PCovariance()
{
return new Parent();
}
public static Child CCovariance()
{
return new Child();
}
static void Main(string[] args)
{
CovarianceHandler handler = PCovariance;
Console.WriteLine(handler().GetType().ToString());
CovarianceHandler handler1 = CCovariance;
Console.WriteLine(handler1().GetType().ToString());
}
}
What is Contravariance in Delegates?
we are able to call PContravariance having parameter type [parent] less derived than the type declared in the delegate signature using ContraVariance. By using this, we can have a single event handler having base type as parameter type and use it with methods having derived type as parameter type for calling.
Example
using System;
class Parent
{
}
class Child: Parent
{
}
class Program
{
public delegate Parent ContravarianceHandler(Child c);
public static Parent PContravariance(Parent p)
{
return p;
}
public static Parent CContravariance(Child c)
{
return c as Parent;
}
static void Main(string[] args)
{
ContravarianceHandler handler = PContravariance;
Console.WriteLine(handler(new Child()).GetType().ToString());
ContravarianceHandler handler1 = CContravariance;
Console.WriteLine(handler1(new Child()).GetType().ToString());
}
}
I am ending things here. I hope this article will be helpful for all.