Click here to Skip to main content
15,867,686 members
Articles / Programming Languages / C#

Covariance and Contravariance in C# 4.0

Rate me:
Please Sign up or sign in to vote.
5.00/5 (4 votes)
16 Oct 2014CPOL2 min read 18.5K   16   17
Covariance and contravariance in C# 4.0

Introduction

In this whole article, we will learn all about Covariance and Contravariance, what were the issues with development before these two.

Definition

These two Covariance and Contravariance have been introduced in C#4.0. As per MSDN, we simply define:

“Covariance and contravariance enable implicit reference conversion for array types, delegate types, and generic type arguments. Covariance preserves assignment compatibility and contravariance reverses it.

In simple words, we can say Covariance and Contravariance are the polymorphism extensions to array types, delegate types, and generic type (we will see in the coming sections).

Issue Before These Two

What were the issues before the invention of these two. Let's consider the following example:

C#
class GrandFather
{
	
}

class Son : GrandFather
{
	
}

class GrandSon : GrandFather
{
	
}

You can see that we are using inheritance, GrandFather is a parent class to Son and GrandSon. As per polymorphism, we can do this:

C#
GrandFather father = new Son();
father   = new GrandSon();

If the above statement is correct, then the following statement should also be correct:

C#
//will throw exception prior to version 4.0
IEnumerable<GrandFather> fathers = new List<Son>();

doesn’t it somehow violate polymorphism? :)

Now, try this in C# 4.0:

C#
//will work fine with version 4.0
IEnumerable<GrandFather> fathers = new List<Son>();

In the above IEnumerable<out t="">, an out parameter of type T.

Consider the following method is in the class:

C#
static void ParentalObject(object o)
{
	//method signature
}
C#
Action<Object> actionObj = ParentalObject;

and we can assign this instantiated object to:

C#
Action<Object> actionObj1 = actionObj;

instantiated object with more derived type arguments.

Array Covariance

This is nothing but implicit conversion of an array of a more derived type to an array of a less derived type. Unfortunately, this is not type safe.

C#
object[] strArray = new string[10];
strArray[0] = 1; //will throw runtime exception

In the above example, our object array is of string type, but we are assigning integer value to one of its elements, it will not throw any compile-time exception, but it will throw runtime exception.

Delegate Covariance

This type of Covariance is also called as method group variance. From MSDN,
you can assign to delegates not only methods that have matching signatures, but also methods that return more derived types (covariance) or that accept parameters that have less derived types (contravariance) than that specified by the delegate type. This includes both generic and non-generic delegates.

C#
static string Parental()
{
	return "Grandfather name is: Lala Bhagwan Das";
}

and see the following:

C#
Func<object> parentalLambda = () => Parental(); //lambda expression
Func<object> parentalFunc = Parental; //Grouped

Now, consider the following method in a class:

C#
static string ParentalObject(object obj)
{
	//method signature
}

Contravariance. A delegate specifies a parameter type as string, but can assign a method that takes an object.

C#
Action<String> parentalDel = ParentalObject;

Variance in Generic Type Parameters

As per MSDNyou can enable implicit conversion between delegates, so that generic delegates that have different types specified by generic type parameters can be assigned to each other, if the types are inherited from each other as required by variance.

To enable implicit conversion, you must explicitly declare generic parameters in a delegate as covariant or contravariant by using the in or out keyword.

Consider the below code:

C#
delegate T ParentalGenericDelegate<out T>();

In the above, we declared type T as a contravariant by using the out keyword.

C#
ParentalGenericDelegate<string> grandFatherName = () => "Grandfather name is: Lala Bhagwan Das";

Above shows how we can create a delegate which has a generic type parameter.

C#
ParentalGenericDelegate<object> anotherGenericDelegate = () => grandFatherName;

The above statement is correct, we can assign delegates to each-other and type T is declared as covariant.

Conclusion

We can say Covariance and Contravariance are the polymorphism extensions to array types, delegate types, and generic type (we will see in the coming sections).

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Chief Technology Officer
India India
Learning never ends.

Comments and Discussions

 
GeneralMy Vote 5 Pin
Shemeemsha (ഷെമീംഷ)29-Oct-14 20:12
Shemeemsha (ഷെമീംഷ)29-Oct-14 20:12 
GeneralRe: My Vote 5 Pin
Gaurav Aroraa29-Oct-14 21:08
professionalGaurav Aroraa29-Oct-14 21:08 
GeneralSimple and easy to understand Pin
Shuby Arora25-Oct-14 8:30
Shuby Arora25-Oct-14 8:30 
I reached here while searching difference between Covariance and Contravariance in C#. I found this post simpler and easy to understand. Keep posting more good things
GeneralRe: Simple and easy to understand Pin
Gaurav Aroraa25-Oct-14 9:01
professionalGaurav Aroraa25-Oct-14 9:01 
GeneralRe: Simple and easy to understand Pin
Shuby Arora25-Oct-14 23:48
Shuby Arora25-Oct-14 23:48 
GeneralRe: Simple and easy to understand Pin
Gaurav Aroraa25-Oct-14 23:57
professionalGaurav Aroraa25-Oct-14 23:57 
GeneralYour article? Pin
Ansgar Hellwig21-Oct-14 22:32
professionalAnsgar Hellwig21-Oct-14 22:32 
GeneralRe: Your article? Pin
Gaurav Aroraa21-Oct-14 22:50
professionalGaurav Aroraa21-Oct-14 22:50 
QuestionQuestion Pin
bbotond9020-Oct-14 22:38
bbotond9020-Oct-14 22:38 
AnswerRe: Question Pin
Ansgar Hellwig21-Oct-14 22:34
professionalAnsgar Hellwig21-Oct-14 22:34 
GeneralRe: Question Pin
Gaurav Aroraa21-Oct-14 22:47
professionalGaurav Aroraa21-Oct-14 22:47 
GeneralRe: Question Pin
Shuby Arora26-Oct-14 0:11
Shuby Arora26-Oct-14 0:11 
GeneralRe: Question Pin
bbotond9022-Oct-14 22:32
bbotond9022-Oct-14 22:32 
GeneralRe: Question Pin
Gaurav Aroraa25-Oct-14 2:36
professionalGaurav Aroraa25-Oct-14 2:36 
AnswerRe: Question Pin
Gaurav Aroraa21-Oct-14 22:39
professionalGaurav Aroraa21-Oct-14 22:39 
GeneralRe: Question Pin
bbotond9022-Oct-14 22:33
bbotond9022-Oct-14 22:33 
GeneralRe: Question Pin
Gaurav Aroraa25-Oct-14 2:35
professionalGaurav Aroraa25-Oct-14 2:35 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.