Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Return type inheritance 1

Status
Not open for further replies.

jmcpher

Programmer
Jun 4, 2001
84
US
I have the following setup:

interface A {
...
}

interface B {
A foo ();
}

class C : A {
...
}

class D : B {
C foo ();
}

So basically, I want class D to return a specific type (C) while at the same time implementing interface B which wants a more general type returned (A). One would think that since C implements A, returning C would be just fine when A is asked for.

I am 100% sure that this could be done by the compiler, if only Microsoft would check the inheritance tree to make sure that C was an A. Anyone have any ideas about how to make it work without getting Microsoft to do a rewrite?

"Programming is like sex, one mistake and you have to support it forever."

John

johnmc@mvmills.com
 
What you are asking for is called "covariance". .Net supports array covariance (object[] oa = new string[10] is legal in other words, which is a nice feature), but not method covariance in overrides in derived classes and interface implementations.

There isn't a general solution to the problem without changing the compiler/language, but, for what it is worth, there is a solution for the specific case you posed (though you may not like it, because it doesn't have the elegance of covariance).

--
class D : B {
A B.foo() {return foo();}
public C foo() {return new C();}
}
--

At first you may think this is illegal because of two reasons:
1) overloads differing only by return type are not allowed
2) The foo that returns an "A" looks like infinite recursion.

but, it is in fact legal because
1) The "A" version is visible only via the interface. The methods differ by more than return type.
2) the delegation call is via the "this" pointer (which is not of type "B"), so the call in the first "foo" is to the "other" foo.

The code above solves the problem as it occurs in your example, but it would be nice if Covariance was supported directly.



 
You will be required to implement in D the A B.foo() and the C foo() and the followings are working:
class D : B
{
A B.foo(){return null;}
C foo () {return null;}
}


class D : B
{
A B.foo(){return null;}
object foo() { return null;}
}

class D : B
{
A B.foo(){return null;}
double foo (){return Double.Epsilon;}

}
-obislavu-
 
Thanks Cheiron, that is exactly what I was looking for, and although it isn't as elegant as having the compiler handle it for you (which pretty much any language but C is all about), it still achieves the desired result.

Unfortunately I decided to change the names of the functions in my interfaces (since I was writing them anyway, it was all just to figure out if it could be done), but I will use your helpful information in the future I am sure.

Once again, thanks for the dead on help.

"Programming is like sex, one mistake and you have to support it forever."

John

johnmc@mvmills.com
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top