Wednesday, February 1, 2017

Covariance and Contravariance in C#:

Covariance means we can substitute derived type in place of Base type. And Contravariance means we can substitute base type in place of derived type.

Covariance and Contravariance allow flexible class hierarchy.

class Animal
{

}
class Lion: Animal
{

}
class Cat : Lion
{
   
}

In above hierarchy you can use
Animal obj = new Lion();
Animal obj1 = new Cat();

But reverse is not allowed
Means
Lion obj3 = new Animal ()
Will give an error.
Covariance allows to use derived type where base is expected.

Covariance with delegate:


Covariance in delegates allows flexibility in return type with delegate methods.

public delegate Animal covarDel(Big mc);
 
class Program
{
 
    static Lion Method1(Big bg)
    {
        Console.WriteLine("Method1");
    
        return new Lion();
    }
    static Animal Method2(Big bg)
    {
        Console.WriteLine("Method2");
    
        return new Animal();
    }
        
    static void Main(string[] args)
    {
        covarDel del = Method1;
 
        Animal sm = del(new Lion());
    }
}


In above example delegate covarDel was expected a method whose return type is Animal , but we have assign a method with return type Lion, And it is perfectly fine.

Contravariance:


Contravariance allows to use base type where derived is expected.
Contravariance is applied to parameters. Contravariance allow a method with parameter of base class to assign in a delegate which has expected the method with parameter of derived class.
delegate Animal covarDel(Lion mc);
 
class Program
{
 
    static Lion Method1(Animal bg)
    {
        Console.WriteLine("Method1");
        return new Big();
    }
    static Animal Method2(Lion bg)
    {
        Console.WriteLine("Method2");
        return new Small();
    }
 
 
    static Lion Method3(Animal sml)
    {
        Console.WriteLine("Method3");
        
        return new Small();
    }
    static void Main(string[] args)
    {
        covarDel del = Method1;
        del += Method2;
        del += Method3;
 
        Animal sm = del(new Lion());
}

In C#, covariance and contravariance are supported for reference types only. 

1.     Array of reference type are covariance from C# 1.0

Below statement is perfectly valid

Animal[]  objArr = new Lion[10];
 But array of value type is not covariant
Below statement will give error [compile time error]
Long[] arr= new int[100]
Generic collection was not covariant
List lstBaseVO = new List()
Will give error. In .Net 4.0 they have they have tried to make it work by using IEnumerable.

IEnumerable objBaseLst = new List();

The above statement is valid because, in .NET 4.0, List : IEnumerable where type ‘T’ is marked as covariant.

2.     Covariance from method to delegate introduced in C# 2.0 ( in case of return type as described in above example.)



























No comments:

Followers

Link