Click here to Skip to main content
Licence CPOL
First Posted 5 Oct 2009
Views 12,021
Bookmarked 2 times

Covariance and Contravariance in C#

By Sohel_Rana | 28 Mar 2010 | Technical Blog
Covariance and Contravariance in C#

1

2
2 votes, 50.0%
3

4
2 votes, 50.0%
5
3.57/5 - 4 votes
μ 3.57, σa 2.02 [?]
A Technical Blog article. View original blog here.[^]

In C#, roughly we can say that covariance means we can substitute derived type in place of base type. Contravariance means we can substitute base class in place of derived class (you are thinking it's not possible, right? We'll see how it's possible). To get a detailed discussion on what covariance and contravariance are, follow the great post on Eric Lippert's Blog or Visit Wikipedia

In C#, covariance and contravariance are supported only for reference types. We will discuss few covariance and contravariance supports in C#. For this example, just take a look at the following class hierarchy as we are going to use the class hierarchy for all the examples in this post:

ContraCo

Figure: Class hierarchy
  1. From C# 1.0, arrays where the element type is reference type are covariant. For example, the following statement in C# is OK.
    Animal[] animals=new Mammal[10];

    In the above code, mammal can be stored in animals array as mammal is derived from Animal. But remember, this is only true for reference types. Why this covariance only for reference types but not for value type? It's because for reference types, the array originally keeps only pointers to the original object and base pointer can refer to derived types. In case of value type, the original value is stored in array itself so the size may vary depending on the type. So covariance is not supported for array of values. For example, the following statement will not compile:

    long[] arr = new int[100];
  2. Covariance from method to delegates were included in C# 2.0. In the following code snippets (which is valid in C# 2.0 and later), you'll find that return type supports covariant. The original delegate has return type of Animal. But the method we have assigned (here, CopyMammal) to a variable (here, cfunc) has return type Mammal. So we can see that covariance is supported in return types.

    //delegate which take no arguments but return animal
    delegate Animal copy(); 
    
    /// <summary> 
    /// method which delegate copy can accepts. 
    /// </summary> 
    /// <returns>Mammal</returns> 
    Mammal copyMammal() 
    { 
    return new Mammal(); 
    }

    The following statement is valid and an example of return type covariance.

    //an assignment statement where covariant occurs by allowing 
    //Mammal return type in place of Animal return type
    copy cfunc = copyMammal;
  3. Contravariance is supported in parameters. Let's take a look at the following code snippets for understanding how contravariance works in parameters types:
    //delegate which take one mammal argument and return nothing 
    delegate void CopyState(Mammal a); 
      
    void copyMammalState(Mammal mammal) 
    { 
    } 
      
    void copyAnimalState(Animal mammal) 
    { 
    } 
      
    void CopyGiraffeSate(Giraffe giraffe) 
    {  
    }

    Now the following code will compile as contravariance is supported here. This is contravariance since we are using Animal parameter of CopyAnimalState in place of Mammal defined in CopyState delegate.

    CopyState cs1 = copyAnimalState; 

    But the following code will not be supported as covariance is not supported in parameters.

    CopyState cs2 = CopyGiraffeSate; 

    The above is not valid in C#. But why is it not valid? Let's explain a bit. For the sake of argument, think that the above statement is valid. Then anybody can call the cs2 with a Tiger element as shown below:

    CopyState cs2 = CopyGiraffeSate;
    Tiger tiger = new Tiger();
    cs2(tiger);

    If covariance would support here, then the above statement would generate an exception as cs2 can handle Giraffe but not Tiger.

C# 4.0 has extended the co and contravariance further for generic types and interfaces. Hope I'll post on it later. Some useful links on covariance and contravariance are as follows:

License

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

About the Author

Sohel_Rana

Web Developer

Bangladesh Bangladesh

Member
Sohel Rana is currently working as Software Engineer in a software firm in Dhaka, Bangladesh. He has years of expertise in working with products like SharePoint, Ektron, DotNetNuke. He's main expertise is in the area of SharePoint.
 
He likes to learn new technologies. He likes to listen music in his spare time.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board. (secure sign-in)
 
Search this forum  
 FAQ
    Noise  Layout  Per page   
  Refresh
GeneralMy vote of 3 Pinmemberram.yadav@viitonline21:51 6 May '11  
GeneralRe: My vote of 3 PinmemberRavi Sant4:43 17 Jun '11  

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

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

Permalink | Advertise | Privacy | Mobile
Web03 | 2.5.120210.1 | Last Updated 29 Mar 2010
Article Copyright 2009 by Sohel_Rana
Everything else Copyright © CodeProject, 1999-2012
Terms of Use
Layout: fixed | fluid