views:

591

answers:

3

There are quite a few questions & answers about hacking around the limitation of C# not allowing method return (and argument) types to be changed to compatible types on overrides, but why does this limitation exist, either in the C# compiler or in the CLR? As I an see, there is nothing that could break if co/contra-variance was allowed, so what is the reasoning behind it?

A similar question could be asked for widening access parameters - eg overriding a protected internal method with a public method (something which Java supports, IIRC)

A: 

It does, you just have to wait for VS2010/.Net 4.0.

Joel Coehoorn
This is only the case for interfaces though, not concrete types
JaredPar
But what was the reason for leaving it out in the first place? It seems a pretty useful thing to have, eg for the Factory pattern
thecoop
@JaredPar - interfaces + delegates ;-p
Marc Gravell
"But what was the reason for leaving it out in the first place?"See: http://blog.ryjones.org/2005/07/12/product-development/
Levi
This is incorrect. C# 4.0 does NOT add return type covariance. We've added generic type variance, which is completely different.
Eric Lippert
A: 

To expand on Joel's answer - the CLR has supported limited variance for a long time, but the C# compiler doesn't use them until 4.0 with the new "in" and "out" modifiers on generic interfaces and delegates. The reasons are complicated, and I would get into a mess trying to explain, but it isn't as simple as it seems.

Re making a "protected internal" method into a "public" method; you can do this with method hiding:

public new void Foo(...) { base.Foo(...); }

(as long as the arguments etc are all also public) - any use?

Marc Gravell
Yes, CLR 2 supported generic type variance. But it did not support return type covariance.
Eric Lippert
Method hiding would work, but it wouldn't act like a virtual method - a call on an instance of the supertype wouldn't be dispatched to the public override
thecoop
Indeed; it has limitations... and because you can't override and "new" the same signature in the same type, you can't achieve proper virtual unless you introduce an *extra* type and an *extra* virtual call.
Marc Gravell
Bad answer. generics variance != override variance; method hiding != overriding
Qwertie
+3  A: 

Eric Lippert already answered this way better than I could.

Check out his series on Covariance and Contravariance in C#

and

How does C# 4.0 Generic Covariance & Contra-variance Implmeneted?

EDIT: Eric pointed out that he doesn't talk about return type convariance but I decided to keep the link in this answer because it is a cool series of articles and someone might find it useful if looking up this topic.

This feature has been requested and almost 5 years ago Microsoft has responded with "Thanks for logging this. We hear this request a lot. We'll consider it for the next release."

And now I'll quote Jon Skeet because it would not be a proper answer on StackOverflow without an answer by Jon Skeet. Covariance and void return types

I strongly suspect that the answer lies in the implementation of the CLR rather than in any deep semantic reason - the CLR probably needs to know whether or not there's going to be a return value, in order to do appropriate things with the stack. Even so, it seems a bit of a pity, in terms of elegance. I can't say I've ever felt the need for this in real life, and it would be reasonably easy to fake (for up to four parameters) in .NET 3.5 just by writing a converter from Func to Action, Func to Action etc. It niggles a bit though :)

Robert Kozak
I know implmenedted is spelled wrong. But I just linked to it directly.
Robert Kozak
No, I have never answered this question. Those articles are about generic type variance. This question is about return type covariance. In my articles on generic variance, I explicitly call out that I am NOT talking about return type variance.
Eric Lippert
doh. My failing memory. I read them months ago and didn't reread them before posting this answer. :)
Robert Kozak
Again, I'm not referring to covariance between void and other object types, I'm referring to covariance on method overrides - overriding a method that returns an object with one that returns a string
thecoop