13

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)

thecoop
  • 45,220
  • 19
  • 132
  • 189

5 Answers5

3

This answer is not talking about C#, but it helped me understand the issues better and maybe it will help others: Why is there no parameter contra-variance for overriding?

Community
  • 1
  • 1
3

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<X> to Action<X>, Func<X,Y> to Action<X,Y> etc. It niggles a bit though :)

Community
  • 1
  • 1
Robert Kozak
  • 2,043
  • 17
  • 33
  • I know implmenedted is spelled wrong. But I just linked to it directly. – Robert Kozak May 07 '09 at 22:03
  • 6
    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 May 08 '09 at 05:37
  • doh. My failing memory. I read them months ago and didn't reread them before posting this answer. :) – Robert Kozak May 08 '09 at 17:30
  • 1
    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 Nov 13 '09 at 11:56
0

Seams introducing covariance of return value has no essential drawback as Java and C++ have used. However, there's real confusion cased by introducing contra-variance of formal parameter. I think this answer https://stackoverflow.com/a/3010614/1443505 in C++ is also valid for C#.

Community
  • 1
  • 1
ivenxu
  • 639
  • 4
  • 16
-1

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

Joel Coehoorn
  • 399,467
  • 113
  • 570
  • 794
-1

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
  • 1,026,079
  • 266
  • 2,566
  • 2,900
  • Yes, CLR 2 supported generic type variance. But it did not support return type covariance. – Eric Lippert May 08 '09 at 06:14
  • 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 May 08 '09 at 09:44
  • 1
    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 May 08 '09 at 09:50
  • 1
    Bad answer. generics variance != override variance; method hiding != overriding – Qwertie Apr 23 '10 at 14:15