Calling an Inherited function from the base class [C#]

Shaitan00

Junior Contributor
Joined
Aug 11, 2003
Messages
358
Location
Hell
I have a class [BaseClass] that has a the following code:
Code:
...
	if (SOMETHING)
	{
		A(nSomething);
		return true;
	}
	return false;
}

public virtual void A(int nSomething)
{}

Then I have a class that inherists from BaseClass called [CharacterClass] and it has the override function of A(int nSomething) as follows:
Code:
public override void A(int nSomething)
{
	// DO ALL THE REAL WORK
}

What I was expecting was that in the BaseClass when I called A(nSomething) I hoping it would actually use the function in CharacterClass (the inherited function) as opposed to the virtual one in BaseClass itself.
As you could expect, the code in CharacterClass [A(nSomething)] is never executed, instead the virtual function in the base class BaseClass is run - which has nothing in it ...

So, obviouslly I need a way around it - is there anyway to accomplish what I am trying to do? The code to launch "A" should be in the BaseClass but the actual effect of "A" needs to be in the inherited classes, but how the hell do I accomplish that?
Any ideas, hints, and help would be greatly appreciated, thanks
 
One way to do this is by utilizing delegates. A delegate is basically a pointer to a method that has the specified "method signature". As long as this signature matches the one declared in the delegate's definition you can execute the delegate in the context of the underlying method.

To solve your problem I would have a protected delegate in the base class. The child class accesses this delegate in its constructor and sets it up to execute one of its methods.

Example:
C#:
public class MyBaseClass
{
    protected delegate void ParentClassMethodDelegate();

    protected ParentClassMethodDelegate _del;

    public void ParentClassMethod()
    {
        // if a child is using the delegate...
        if (_del != null)
        {
            // fire the method assigned by the child
            _del();
        }
    }
}

public class MyChildClass : MyBaseClass
{
    public MyChildClass()
    {
        _del = new ParentClassMethodDelegate(ChildClassMethod);
    }

    // this method will be fired by the parent
    private void ChildClassMethod()
    {
        Console.WriteLine("Hello from the child!");
    }
}
The following code...
C#:
MyChildClass c = new MyChildClass();
c.ParentClassMethod();
...will simply display "Hello from the child!" on the screen. You will notice that although we called the parent class method we actually executed the child class method. You can use this approach even if your methods return values and/or take parameters:
C#:
public class MyBaseClass
{
    protected delegate int ParentClassMethodDelegate(int a, int b);

    protected ParentClassMethodDelegate _del;

    public int ParentClassMethod(int a, int b)
    {
        if (_del != null)
        {
            return _del(a, b);
        }

        throw new InvalidOperationException("Delegate has not been implemented yet!");
    }
}

public class MyChildClass : MyBaseClass
{
    public MyChildClass()
    {
        _del = new ParentClassMethodDelegate(ChildClassMethod);
    }

    private int ChildClassMethod(int a, int b)
    {
        return a + b;
    }
}
 
What I was expecting was that in the BaseClass when I called A(nSomething) I hoping it would actually use the function in CharacterClass (the inherited function) as opposed to the virtual one in BaseClass itself.
A call to a virtual function should (and will) execute the most derived instance of the function present. So in your derived class the overriding function will be called unless you use some specific mechanism (the base keyword, or a direct typed reference to a base class in VB) If ot doesn't then theres something wrong with reality in your program.

As you could expect, the code in CharacterClass [A(nSomething)] is never executed, instead the virtual function in the base class BaseClass is run - which has nothing in it ...
The behavior where the base version of a virtual function is called from a derived context without specific call to base is totally conter intuative and possible contrary to the runtime design. You expected the correct behavior. if this behavior isn't happening then there is something wrong.

So, obviouslly I need a way around it - is there anyway to accomplish what I am trying to do? The code to launch "A" should be in the BaseClass but the actual effect of "A" needs to be in the inherited classes, but how the hell do I accomplish that?
Any ideas, hints, and help would be greatly appreciated, thanks

Make the base function abstract? afterall if its empty and virtual and inheritors are required to override then it pretty much already is abstract by agreement. Of course that means you'd need BaseClass ot be abstract which may or may not work for you.

If you can repeatably make this weird behavior occur i'd like to see working code, inheritance doesn't work the way you say it seems to be and you shouldn't be able to do what you say you have.
 
Your expectations of the behavior of the override method are correct. If you override a virtual method in a subclass (CharacterClass in this case), the overriding method is automatically called when the virtual method (A) is called.

That it isnt happening in your code means that something else is wrong. My first guess is, that the object isnt a CharacterClass, but a BaseClass. Check where you create the object and see if you create a CharacterClass or a BaseClass. My first guess would be that you actually create a BaseClass object instead of a CharacterClass. In that case the compiler/runtime dont know about the CharacterClass and the override, and will call the implementation in the baseclass.
Virtual-override only works when you create the subclass. You can cast it to the baseclass without a problem, the override still exists.
One trick would be to make it abstract instead of virtual. That forces the class to become abstact, then the compiler wont allow you to create it anymore. You must create the CharacterClass subclass. If you find a compile problem with the class as abstract, you probably found the actual problem why it doesnt work at this moment.

I'll use a bit of C++ analogy to explain a bit what I think happens with virtual-override. Somewhere the compiler creates a table of all the virtual methods of an object. In that table there is an adress of the 'current' implementation for a virtual method. When a subclass overrides a virtual method, it overwrites the adress of that 'current' implementation. That means that if the object is casted to something else in the object hierarchy, the override is still 'registered' as the implementation to use. However, if you only create the baseclass, the subclass can never overwrite the information -> you keep the original virtual method without implementation. (offcourse this is not exactly what happens, but it is pretty close to what happens in C++ ;) )
 
Shaitan00,

My approach will work if, from within a parent class method, you need to execute a method that is in a child class. This will allow you to simulate what you are trying to do.
 
I chose to go the way of using ABSTRACT class [for BaseClass], seems to be working great so far (as opposed to virtual, which wasn't working)...

And I made sure I wasn't actually creating an instance of BaseClass, it was actually of ZombieClass which inherists from BaseCharacter (which inherists from BaseClass)....

Oddly enough I would much prefer have ZombieClass perform function A(nSomething) so I want to "skip" the defintion of function "A" in BaseCharacter (have it abstract in BaseClass, not defined or abstract/virtual in BaseCharacter, and DEFINED in ZombieClass) ... Hope that is a clear explanation ....

So, in BaseClass I have the following:
public abstract void A(int nSomething);

And in ZombieClass I have the followng:
public override void A(int nSomething);

As you can see I want to SKIP over BaseCharacter, but it won't let me, no matter what I try to put in BaseCharacter:
If I put nothing = BaseCharacter does not implement inherited abstract member 'BaseClass.A(int)'
If I put Virtual = BaseCharacter' does not implement inherited abstract member 'BaseClass.A(int)'
If I put Abstract = BaseCharacter.A(int)' hides inherited abstract member 'BaseClass.A(int)'

Any clues? Is this do-able?
 
It might be easier if you could attach the actual code, or failing that a cut down versin of the relevant classes and methods that exhibit the problem / demonstrate the expected behaviour.
 
Not sure where I went wrong - went over all your comments and decided to re-write the outline structure of my classes - not sure what I changed but using the typical Virtual/Override functionality seems to be working perfectly fine now (now that I followed all your comments)....

Looks like it is working fine.
Thanks a LOT for all the feedback ...
 
Back
Top