-1

I read recently about covariance and contravariance - little code example below:

public class BaseClass{
    public int x = 1;

    public static void print(BaseClass objClass)
    {
        Console.WriteLine(objClass.GetType().Name + " " + objClass.x); 
    }
}

public class DerivedClass : BaseClass{
    public int x = 2;
}

public class Program
{
    public static void Main(string[] args)
    {
        BaseClass bC = new BaseClass();
        DerivedClass dC = new DerivedClass();

        BaseClass.print(bC); //DerivedClass 1
        DerivedClass.print(bC); //DerivedClass 1
        BaseClass.print(dC); //DerivedClass 1
        DerivedClass.print(dC); //DerivedClass 1
    }
}

My question is - what contravariance give us in practice ? I know that I can pass object of DerivedClass as argument into BaseClass method (where parameter is BaseClass type) but what are the benefits of such operation ? And why when I pass DerivedClass object it returns me value of x in BaseClass ?

Maybe this is bad example for explain benefits of contravariance then I would be grateful for another example.

Hadrian
  • 55
  • 1
  • 7
  • 6
    This doesn't use contravariance anywhere. – Lee Nov 09 '16 at 16:38
  • Wow - so there are misleading tutorial on the internet ;) But anyway - Can someone explain me why when I pass DerivedClass object it returns me value of x in BaseClass ? If it's nothing change why we can do that ? PS. Sinatr - thanks for that link – Hadrian Nov 09 '16 at 16:46
  • 1
    You are confusing variance with inheritance/polymorphism. – Mr Anderson Nov 09 '16 at 16:46
  • Ok, I understand, sorry for confusing- but could someone answer me for my question above ? I would be very grateful! – Hadrian Nov 09 '16 at 16:49

1 Answers1

1

why when I pass DerivedClass object it returns me value of x in BaseClass ?

You are hiding the field in the derived class. In effect DerivedClass has two x fields - one from the base class, one from the derived class. Since the parameter to print is of type BaseClass the compiler will bind objClass.x to the field in the base class.

If instead you have a virtual property and an override:

public class BaseClass{
    public virtual int x {get {return 1;}}

    public static void print(BaseClass objClass)
    {
        Console.WriteLine(objClass.GetType().Name + " " + objClass.x); 
    }
}

public class DerivedClass : BaseClass{
    public override int x {get {return 2;}}
}

Or just set the base field to a different value in the derived class:

public class DerivedClass : BaseClass{
    public DerivedClass() {x = 2;}
}

You would see the results you expect.

D Stanley
  • 149,601
  • 11
  • 178
  • 240