I'm having a problem with a program I'm writing, where my virtual functions don't seem to be behaving the way they should.
I have a class with a virtual function, and a derived class that overrides it. When I call the function, the override isn't called, but the base is. This is something I've done a million times before and I have no idea how that behaviour can break in such as simple case.
As an example:
public class ClassA
{
public DoStuff()
{
MyVirtual()
}
protected virtual MyVirtual()
{
Console.WriteLine("Base MyVirtual Called");
}
}
public class ClassB : ClassA
{
protected override MyVirtual()
{
Console.WriteLine("Overridden MyVirtual Called");
}
}
ClassA test = new ClassB;
test.DoStuff();
This example is just for effect (I haven't compiled it to check it, I'm just demonstrating). I just want to know what can break that so the override isn't called. I can't paste my specific code, but it is theoretically as simple as that.
The inheritance hierarchy is just the two classes
There's no sealed modifiers
The class is created via a simple call to new for the inherited class
The virtual function is protected and called from a public function in the base class just like that
How could that possibly break or what could interfere with that behaviour? The project is quite complicated, but this is nothing new that I'm implementing. In my specific code, there is even another virtual function written exactly the same way and inherited the same way, that works fine. I even made the new function by copy/pasting that one and renaming, so the syntax should be identical (I did rebuild them from scratch when they didn't work, but no difference to their behaviour).
Anyway, I'm at my wits end and I can't spend days searching for an obscure reason for this, so any ideas of where to start looking would be hugely appreciated.
If you fix the errors it compiles successfully and behaves as you would expect.
Fixed version:
public class ClassA
{
public void DoStuff()
{
MyVirtual();
}
protected virtual void MyVirtual()
{
Console.WriteLine("Base MyVirtual Called");
}
}
public class ClassB : ClassA
{
protected override void MyVirtual()
{
Console.WriteLine("Overridden MyVirtual Called");
}
}
ClassA test = new ClassB();
test.DoStuff();
Output:
Overridden MyVirtual Called
This basically means that, contrary to your statements, your code isn't "theoretically as simple as that", my guess is that you are not actually overriding in B class.
If you have several classes in the inheritance chain, you may want to check that all the methods with the same name in those classes (if they exist) have "override"
Related
I want to ask this question because of some safety mechanism for my code.
This may seem like useless, but it already made me lose much time debugging.
public class AnimalClass
{
virtual void Mod{}
virtual void UpdateSomeValues{}
}
public class CatClass : AnimalClass
{
override void Mod{}
override void UpdateSomeValues{}
}
Is there a way in C# to automatically fire up Cat's UpdateSomeValues function whenever Cat's Mod function is called (without having to call it manually from Cat's Mod function)?
And if possible, make it the same for all derived classes?
No. You could solve that issue by introducing another, protected method that derived classes can override, and make the public one call into it once all the necessary processing is done:
public class AnimalClass
{
public void Mod()
{
// do stuff
ModImpl();
}
protected virtual ModImpl() {}
}
With that derived classes would implement ModImpl() if they want to do some extra processing, and you're sure that // do stuff still happens when Mod is called.
I came across a posting where it is said that MustBeCalled() method will get called if we have the Abstract class do the calling in this manner.
public abstract class AbstractClass
{
public void PerformThisFunction()
{
MustBeCalled();
AbstractMethod();
}
public void MustBeCalled()
{
//this must be called when AbstractMethod is invoked
}
//could also be public if desired
protected abstract void AbstractMethod();
}
public class ImplementClass : AbstractClass
{
protected override void AbstractMethod()
{
//when called, base.MustBeCalled() must be called.
//how can i enforce this?
}
}
But how does MustBeCalled() method get called?
In what order things are called here?
If you call PerformFunction() first, then everything will execute in the intended order, where that order is specified in the order of the lines of code in PerformFunction(). If you call AbstractMethod() directly, there's no guarantee that MustBeCalled() will ever be called. However, I notice that you have AbstractMethod() marked as protected, which means that outside consumers of your class will not be able to call it directly. They'll have to use PerformFunction() -- this is good, as there is now only one public way to invoke your internal methods, and that way guarantees the order that you need.
In truth, there is a level at which you can only guarantee that things happen by choosing to write code to make them happen. You can't, for example, guarantee that code is going to implement a game of Tetris except by actually writing that code and choosing to implement it in such a way that it produces Tetris behavior. The type system and the public/protected/private modifiers can help some by preventing some misuse (as your internals are not accessible and thus cannot be invoked by consumers of your module), but they can only go so far. This is such a case.
You cannot enforce how an implementation to call a method when invoked. The implementation could do its own thing entirely, or do nothing.
public class ImplementClass : AbstractClass
{
protected override void AbstractMethod()
{
// this is a perfectly valid implementation
}
}
A better implementation could be.
public abstract class AbstractClass
{
public void PerformThisFunction()
{
MustBeCalled();
AbstractMethod();
}
private void MustBeCalled()
{
}
protected virtual void AbstractMethod()
{
MustBeCalled();
}
}
This way refactoring tools will at least create the desired boilerplate code:
public class ImplementClass : AbstractClass
{
protected override void AbstractMethod()
{
base.AbstractMethod();
}
}
However, the person overriding AbstractMethod still needs to call base.AbstractMethod, this is not enforced by the compiler at all.
Having code like this:
class X
{
public virtual void Test()
{
}
}
class Y : X
{
public override void Test()
{
base.Test() //added automatically, why?
}
}
Because, by implication, that won't break anything.
Because in most of the cases it makes sense or is even required to call the base class implementation, e.g. virtual Dispose methods (base class needs to be Disposed) or virtual OnXXX methods in WinForms (base class usually fires an event from their OnXXX methods).
Of course if the virtual method is yours and you do not want this behavior I agree that it's pretty annoying ;)
If I have the following:
e.g.
public abstract class ClassA
{
protected abstract void ValidateTransaction();
}
public abstract class ClassB : ClassA
{
protected override void ValidateTransaction()
{
// some custom logic here
}
}
public class ClassC : ClassB
{
protected override void ValidateTransaction()
{
base.ValidateTransaction();
// some additional custom logic here
}
}
So I did not find usages on ClassC's ValidateTransaction. I don't see it being called anywhere.
So then I guess how does this work? I mean it's calling the method at the top of the stack here (calls the ClassB's override method and then includes logic in my ClassC's override of ClassB's method?)
This doesn't make sense to me why or how this works or the intention here.
UPDATED
Ok so I did find a spot where ClassA's PerformTransaction() method is called from a lot of sub classes in our project.
So ClassA now looks like this with more details for you here:
public abstract class ClassA
{
public void PerformTransaction()
{
ValidateTransaction();
// and calls some other code here.
}
protected abstract void ValidateTransaction();
}
Ok then we still have:
public abstract class ClassB : ClassA
{
protected override void ValidateTransaction()
{
// some custom logic here
}
}
public class ClassC : ClassB
{
protected override void ValidateTransaction()
{
base.ValidateTransaction();
// some additional custom logic here
}
}
public class SomeAbritraryClass : ClassC
{
ClassA.PerformTransaction();
...
}
so ClassA.PerformTransaction() is being called in some classes that inherit ClassC.
Well, it calls ClassC's override method... which happens to call ClassB's implementation. It's not "including" the logic of ClassB's implementation directly within the compiled code of ClassC, or anything like that - it's just another method call.
It's not entirely clear what's confusing you - the behaviour, the design intention, or what Find Usages is showing you.
Note that despite your subject line, you're not calling a "base abstract method" - you're calling the implementation of that method. The compiler knows that ClassC derives from ClassB, which is providing an implementation of the method, so it's making that call explicitly. You couldn't do the same thing from ClassB itself, because then base.ValidateTransaction really would be trying to call an abstract base method.
Fun fact: despite this calling a virtual method, it's a non-virtual method call: the compiler knows the exact implementation to use, and bakes that into the call. If it was a virtual call, you'd end up back in the ClassC implementation as that overrides it :)
When the C class override is called, it will first call into B's override and execute some logic there, which will then be extended by C's logic.
They could for all I know be working with the same variables, data. I don't know, cause I don't have all the data.
So then I guess how does this work? I mean it's calling the method at the top of the stack here (calls the ClassB's override method and then includes logic in my ClassC's override of ClassB's method?)
Yes, that's basically what happens. When you call ValidateTransaction on an instance of ClassC, it's method is run. It, then, explicitly executes the base class (ClassB) method, then adds its own additional validation.
You're probably not finding direct usages of ClassB.ValidateTransaction() because there are no instances of ClassB (defined as ClassB) on which this is called. However, any ClassC call will be indirectly using ClassB.ValidateTransaction() through the base.ValidateTransaction() line.
Is there a construct in Java or C# that forces inheriting classes to call the base implementation? You can call super() or base() but is it possible to have it throw a compile-time error if it isn't called? That would be very convenient..
--edit--
I am mainly curious about overriding methods.
There isn't and shouldn't be anything to do that.
The closest thing I can think of off hand if something like having this in the base class:
public virtual void BeforeFoo(){}
public void Foo()
{
this.BeforeFoo();
//do some stuff
this.AfterFoo();
}
public virtual void AfterFoo(){}
And allow the inheriting class override BeforeFoo and/or AfterFoo
Not in Java. It might be possible in C#, but someone else will have to speak to that.
If I understand correctly you want this:
class A {
public void foo() {
// Do superclass stuff
}
}
class B extends A {
public void foo() {
super.foo();
// Do subclass stuff
}
}
What you can do in Java to enforce usage of the superclass foo is something like:
class A {
public final void foo() {
// Do stuff
...
// Then delegate to subclass
fooImpl();
}
protected abstract void fooImpl();
}
class B extends A {
protected void fooImpl() {
// Do subclass stuff
}
}
It's ugly, but it achieves what you want. Otherwise you'll just have to be careful to make sure you call the superclass method.
Maybe you could tinker with your design to fix the problem, rather than using a technical solution. It might not be possible but is probably worth thinking about.
EDIT: Maybe I misunderstood the question. Are you talking about only constructors or methods in general? I assumed methods in general.
The following example throws an InvalidOperationException when the base functionality is not inherited when overriding a method.
This might be useful for scenarios where the method is invoked by some internal API.
i.e. where Foo() is not designed to be invoked directly:
public abstract class ExampleBase {
private bool _baseInvoked;
internal protected virtual void Foo() {
_baseInvoked = true;
// IMPORTANT: This must always be executed!
}
internal void InvokeFoo() {
Foo();
if (!_baseInvoked)
throw new InvalidOperationException("Custom classes must invoke `base.Foo()` when method is overridden.");
}
}
Works:
public class ExampleA : ExampleBase {
protected override void Foo() {
base.Foo();
}
}
Yells:
public class ExampleB : ExampleBase {
protected override void Foo() {
}
}
I use the following technique. Notice that the Hello() method is protected, so it can't be called from outside...
public abstract class Animal
{
protected abstract void Hello();
public void SayHello()
{
//Do some mandatory thing
Console.WriteLine("something mandatory");
Hello();
Console.WriteLine();
}
}
public class Dog : Animal
{
protected override void Hello()
{
Console.WriteLine("woof");
}
}
public class Cat : Animal
{
protected override void Hello()
{
Console.WriteLine("meow");
}
}
Example usage:
static void Main(string[] args)
{
var animals = new List<Animal>()
{
new Cat(),
new Dog(),
new Dog(),
new Dog()
};
animals.ForEach(animal => animal.SayHello());
Console.ReadKey();
}
Which produces:
You may want to look at this (call super antipatern) http://en.wikipedia.org/wiki/Call_super
If I understand correctly you want to enforce that your base class behaviour is not overriden, but still be able to extend it, then I'd use the template method design pattern and in C# don't include the virtual keyword in the method definition.
No. It is not possible. If you have to have a function that does some pre or post action do something like this:
internal class Class1
{
internal virtual void SomeFunc()
{
// no guarantee this code will run
}
internal void MakeSureICanDoSomething()
{
// do pre stuff I have to do
ThisCodeMayNotRun();
// do post stuff I have to do
}
internal virtual void ThisCodeMayNotRun()
{
// this code may or may not run depending on
// the derived class
}
}
I didn't read ALL the replies here; however, I was considering the same question. After reviewing what I REALLY wanted to do, it seemed to me that if I want to FORCE the call to the base method that I should not have declared the base method virtual (override-able) in the first place.
Don't force a base call. Make the parent method do what you want, while calling an overridable (eg: abstract) protected method in its body.
Don't think there's any feasible solution built-in. I'm sure there's separate code analysis tools that can do that, though.
EDIT Misread construct as constructor. Leaving up as CW since it fits a very limited subset of the problem.
In C# you can force this behavior by defining a single constructor having at least one parameter in the base type. This removes the default constructor and forces derived types to explcitly call the specified base or they get a compilation error.
class Parent {
protected Parent(int id) {
}
}
class Child : Parent {
// Does not compile
public Child() {}
// Also does not compile
public Child(int id) { }
// Compiles
public Child() :base(42) {}
}
In java, the compiler can only enforce this in the case of Constructors.
A constructor must be called all the way up the inheritance chain .. ie if Dog extends Animal extends Thing, the constructor for Dog must call a constructor for Animal must call a constructor for Thing.
This is not the case for regular methods, where the programmer must explicitly call a super implementation if necessary.
The only way to enforce some base implementation code to be run is to split override-able code into a separate method call:
public class Super
{
public final void doIt()
{
// cannot be overridden
doItSub();
}
protected void doItSub()
{
// override this
}
}
public class Sub extends Super
{
protected void doItSub()
{
// override logic
}
}
I stumbled on to this post and didn't necessarily like any particular answer, so I figured I would provide my own ...
There is no way in C# to enforce that the base method is called. Therefore coding as such is considered an anti-pattern since a follow-up developer may not realize they must call the base method else the class will be in an incomplete or bad state.
However, I have found circumstances where this type of functionality is required and can be fulfilled accordingly. Usually the derived class needs a resource of the base class. In order to get the resource, which normally might be exposed via a property, it is instead exposed via a method. The derived class has no choice but to call the method to get the resource, therefore ensuring that the base class method is executed.
The next logical question one might ask is why not put it in the constructor instead? The reason is that it may be an order of operations issue. At the time the class is constructed, there may be some inputs still missing.
Does this get away from the question? Yes and no. Yes, it does force the derived class to call a particular base class method. No, it does not do this with the override keyword. Could this be helpful to an individual looking for an answer to this post, maybe.
I'm not preaching this as gospel, and if individuals see a downside to this approach, I would love to hear about it.
On the Android platform there is a Java annotation called 'CallSuper' that enforces the calling of the base method at compile time (although this check is quite basic). Probably the same type of mechanism can be easily implemented in Java in the same exact way. https://developer.android.com/reference/androidx/annotation/CallSuper