10 February 2012

Contravariance: Is it really what it is?

By definition, contravariance referes to a situtaion where you assign base class instance to a child class reference. Let's directly see an example,

class BaseClass
{
}

class ChildClass: BaseClass
{
}

class TestContraVariance
{       
    delegate void SomeContraVariantDelegate(ChildClass argument);

    public void CreateContravariantDelegate()
    {           
        SomeContraVariantDelegate cvd = new SomeContraVariantDelegate(EventHandlerMethod);
    }

    private void EventHandlerMethod(BaseClass arg)
    {
    }
}

Here, you can see the contravariance - Delegate SomeContraVariantDelegate expects a method that accepts ChildClass instance. But, the function EventHandlerMethod accepts an argument of type BaseClass. So, it appears that a base class object is assigned to a child class object which is not possible in normal scenarios. But, is it really what it seems to be? I don't think so. Let me explain,

In the above example, if you see carefully, the delegate calls the method but not method calls delegate. So, when delegate calls EventHandlerMethod it sends a ChildClass instance as parameter. This is perfectly valid because the method accepts BaseClass instance and the delegate passes ChildClass instance. So, actually ChildClass instance is assigned to BaseClass object but not the other way.

So, there exists nothing like assigning assigning BaseClass instance to ChildClass object and hence no contravariance like thing exists too.

2 comments: