Covariance and Contra-variance seems to be scary terms for a very simple and familiar concept. C# 4.0 introduces the notion of Covariance and Contra-variance of generic type parameters for interfaces and delegate types. For delegate types: Covariance and contra-variance provide a degree of flexibility when matching method signatures.
Covariance permits a method to have a more derived return type than what is defined in the delegate. Following example shows how delegates can be used for covariance:
Here the data type returned by WebManager() is of type WebProjects, which derives from the Projects type that is defined in the delegate.
class Projects
{
}
class WebProjects: Projects
{
}
class Program
{
// Define the delegate.
public delegate Projects dlgManager();
public static Projects Manager()
{
return null;
}
public static WebProjects WebManager()
{
return null;
}
static void Main()
{
dlgManager dlgManager1 = Manager;
// Covariance allows this delegate.
dlgManager dlgManager2 = WebManager;
}
}
Contra-variance permits a method with parameter types that are less derived than in the delegate type. Following example shows how delegates can be used for contra-variance:
System.DateTime dtWork;
public Form1()
{
Initialize();
dtWork = new System.DateTime();
this.textBox1.KeyDown += this. MultiPurposeHandler; //works with KeyEventArgs
this.button1.MouseClick += this. MultiPurposeHandler; //works with MouseEventArgs
}
// Event handler for any event with an EventArgs or derived class of EventArgs
private void MultiPurposeHandler(object sender, System.EventArgs e)
{
dtWork = System.DateTime.Now;
}