I think what I'm getting confused about is demonstrated by this, which
backs up what you said
public class A
{
public virtual int whatever( A a )
{
return 1;
}
public int fred(A a)
{
return whatever( a );
}
}
public class B : A
{
public override int whatever( A a )
{
return 2;
}
}
A aa = new A();
B bb = new B();
int z = aa.fred( aa ); // z = 1
int y = aa.fred( bb ); // y = 1
int x = bb.fred( aa ); // x = 2 -- backs up your statement (you could
not cast (B)a in b.whatever() safely)
int w = bb.fred( bb ); // w = 2
"fred" belongs in "A" but calls b.whatever() whenever we use "bb.fred".
Obviously this is no magic derived from the parameter type but the
class pointer "bb.".
From the code workarounds that have been posted many people have come
across this and have their own workaround (as do I) so it's a common
problem/pattern.
My original point was more simple, all I want is the compiler to
"ignore" what I have typed
public override int whatever( B b )
and assume I had typed
public override int whatever( A a )
and everything works as normal. In other words the compiler "always"
traces back to the "root" types of the parameters in the "override"
declaration and if it matches the type of the parameter in the
"virtual" declaration it's happy and replaces what I typed with the
type declared on the "virtual" declarion.
I can now see this would be confusing as the declaration would suggest
that you would always get a "B" when, as we have seen" it could be an
"A".
But...
As one person pointed out you can use "is" to workout if the parameter
is a "B" and cast accordingly so it occurs to me that the compiler
could do something along those lines also.
Could there be a clean way of implementing this in the language I
wonder.
As someone suggested the runtime would have to check parameter types at
runtime and call the appropriate method. So be it. If that's what I
want I take the hit. When the compiler discovers such a "special"
method (declared svirtual maybe) it creates a subroutine call and some
lookup table (populated in the constructor) so that when a call to such
a method is made it does an "is", and looks up the type and calls the
method that matches.
I won't hold my breath waiting for it to be implemented though!
It just seems a common scenario to me, I call methods "A(b)" from layer
"B" knowing that methods in "B" will be called with "b" coming through
and I always need to cast them which as we have seen is unsafe in some
situations. There must be a better way....
Cliff