Raymond Lewallen

Sponsors

The Lounge

Advertisement

Images in this post missing? We recently lost them in a site migration. We're working to restore these as you read this. Should you need an image in an emergency, please contact us at imagehelp@codebetter.com
Covariance and Contravariance

So here is something that came up in a discussion I was having.  It revolved around delegates and their parameter types because we were trying to find an easier way to solve an issue without having to write more code than we really wanted to.  If you program entirely in VB or are not using .Net framework 2.0 with C#, then you are missing out on 2 features of delegates that are very useful: covariance and contravariance.  Now I have personally spent, until very recently, the vast majority of my time in VB and Framework 1.1, so even though I knew about the features, I never fully understood what I could do with them and I was never able to make use of them until now when it came up as part of a way to solve a problem in a program that I am helping a friend with.  He knew nothing of these new features, so maybe there are more of you out there that benefit from this, as it doesn’t seem to be well documented in easy to find places.  Just for fun I tried to google "covariance" and a few other things with no success, so maybe putting this out there will make it easier for others to find.  These are fine examples of how the languages continue to evolve and allow us to create more flexible, maintainable and efficient code.

Covariance basically means that the return value of a method that is referenced by your delegate can have a different return type than that specified by the delegate itself, so long as the return type of the method is a subclass of the return type of the delegate.  In the example below, you can see that MyMethod returns Car, but xyz is calling FunctionTwo, which returns type Toyota.  Because Toyota is derived from Car, this works.

Covariance
public class Car
{ } public class Toyota : Car
{ } class Demo
{ static void Main() { MyMethod abc = FunctionOne; MyMethod xyz = FunctionTwo; } public delegate Car MyMethod(); public static Car FunctionOne() { return new Car(); } public static Toyota FunctionTwo() { return new Toyota(); } }

 

Contravariance is kind of the same thing, but deals with the parameters rather than return types.  Contravariance allows you to use delegate parameters who’s types are those that inherit from the parameter types used in the method the delegate references.  In the following example, you can see that FunctionOne specifies the Car type as the parameter, while the delegate has the signature that specifies Toyota.  Contravariance allows this to happen.

Contravariance
class Demo
{ public delegate void MyMethod(Toyota value); static void Main(string[] args) { MyMethod abc = FunctionOne; MyMethod xyz = FunctionTwo; } public static void FunctionOne(Car value) { } public static void FunctionTwo(Toyota value) { } }

Posted 12-28-2006 6:46 AM by Raymond Lewallen

[Advertisement]

Comments

Andrew Stopford's Weblog wrote C# generics covariance
on 12-28-2006 9:17 AM

I've posted about this before , largely covariance is possible in C# delegates but not featured in

Dave Redding wrote re: Covariance and Contravariance
on 12-29-2006 8:54 AM

These are new terms to me, thanks for the tech tip.  One question I have to ask though is, won't contravariance violate some of the purposes of having a delegate?  

I do see the usefullness of it, but it seems to be one of those aqward "Could be done better a different way" type of things.  For instance, why would'nt i change my parameter type to car, instead of specifying toyota if i know that i'm going to have a function that accepts any kind of "Car" object?

Thanks for the great post!

Raymond Lewallen wrote re: Covariance and Contravariance
on 12-29-2006 9:11 AM

Dave,

A better example would be a method that accepts EventArgs, but you have 2 delegates, one that has a KeyEventArgs and another that has MouseEventArgs.  When some body presses a key or clicks the mouse, you want the same action to happen, so you reference both delegates to the same method because the method EventArgs is a parent class of the delegate's eventargs.  This is the example I believe Microsoft docs use if I remember correctly.

Charlie Calvert's Community Blog wrote Community Convergence XVI
on 12-29-2006 6:55 PM

Welcome to the sixteenth Community Convergence. This column comes out about once a week and is designed

simone_b wrote re: Covariance and Contravariance
on 12-29-2006 8:04 PM

Thanks for the clear explanation Raymond

Dave Redding wrote re: Covariance and Contravariance
on 01-02-2007 7:59 AM

I can see how that would make sense.  Thanks for the reply!

Happy new year!

Dave.

Derick Bailey wrote re: Covariance and Contravariance
on 01-04-2007 8:32 AM

Isn't this just a fancy way of saying "Polymorphism"?

I understand the benefit of using delegates like this, though... I had never tried doing that before and I'll definitely benifit from knowing about this. Thanks for the good post.

Raymond Lewallen wrote re: Covariance and Contravariance
on 01-04-2007 9:16 AM

Derick,

This isn't really polymorphism, but rather it supports polymorphic behavior of objects.

John Thompson wrote re: Covariance and Contravariance
on 01-04-2007 8:23 PM

Thanks for the explaination Raymond!

I had not heard these terms before either, but the technique makes sense.

At least Covariance does, anyway. This is as you say just a utilization of polymorphism.

Controvariance surprised me though. At first I was confused by the fact that a base class of a parameter type would likely have a limited interface relative to the class defined in the delegate parameter list. But then I realized this should not be a problem, because we are only dealing with a delegate parameter which defines a type not an interface. Still assigning a function with a base class parameter type to the delegate seems unusual or at least less useful than assigning sub class. This would seem to imply that you could define your delegated function as:

public void FunctionX(Object value)

My gut reaction is that this seems to undermine the principles of strong typing. Maybe I just need to think about it some more.

Could you also assign a function with a sub class parameter type? Would this still be defined as contravariance or another example of covariance?

TrackBack wrote http://weblogs.asp.net/astopford/archive/2006/12/28/c-generics-covariance.aspx
on 03-19-2007 3:28 PM
http://weblogs.asp.net/astopford/archive/2006/12/28/c-generics-covariance.aspx
TrackBack wrote http://forums.asp.net/thread/1587360.aspx
on 03-19-2007 3:30 PM
http://forums.asp.net/thread/1587360.aspx
TrackBack wrote http://blogs.msdn.com/charlie/archive/2006/12/30/community-convergence-xvi.aspx
on 03-19-2007 3:30 PM
http://blogs.msdn.com/charlie/archive/2006/12/30/community-convergence-xvi.aspx
TrackBack wrote http://msdn2.microsoft.com/en-us/vcsharp/default.aspx
on 03-19-2007 3:31 PM
http://msdn2.microsoft.com/en-us/vcsharp/default.aspx
Vicente wrote re: Covariance and Contravariance
on 08-12-2007 11:16 PM

Hello:

I have a question:

Suppose I have a delegate D and a class A which implements(not inherits) more than two overloads of a method M. Suppose that none of these overloads match exactly the signature of  D, but all of them are elegible for D due to Covariance and Contravariance.

Which overload wins?

Adventures in .net and other Microsoft worlds wrote Generics and covariance/contravariance
on 10-09-2007 12:17 PM

Today I was writing code that looks like this: public interface IChild {} public class GenericSet where TChild : IChild {} public class SpecificSet : GenericSet

Rejani wrote re: Covariance and Contravariance
on 04-14-2008 6:42 AM

Good article.

MVP Factor wrote C# INVARIANZA, COVARIANZA & CONTRAVARIANZA
on 04-27-2009 8:12 PM

Nuestro buen amigo Pete que ya nos ha compartido en el paso muy buenos artículos de XNA, ahora nos comparte

Tramadol. wrote Tramadol.
on 05-30-2009 6:50 PM

Free blog hosting from tramadol anothervision info.

on 05-31-2009 7:14 PM

Vicodin no prescription. Vicodin. Buy vicodin online. Vicodin without prescription. How long does vicodin stay in body. Cheap vicodin cod. Order vicodin es generic.

Amoxicillin. wrote Amoxicillin.
on 06-13-2009 10:35 AM

Amoxicillin. Are greyhounds allergic to amoxicillin. Amoxicillin online no prescription. Taking amoxicillin while pregnant. Amoxicillin yeast infection.

Buy domain onlinevcvpl soma. wrote Buy soma online.
on 06-14-2009 5:57 PM

Buy soma tablets. Buy soma. Buy soma online. Buy soma watson brand online 150 tablets. Buy domain onlinevcvpl soma. Buy soma from mexico online.

Add a Comment

(required)  
(optional)
(required)  
Remember Me?