Monday, May 4, 2026

Of Virtual and Override in C# (Back to Basics)

 *Declaring derived class variable as object of base class is not allowed. 

DerivedClass dc = new ParentClass(); //compiler gives error.

DerivedClass dc = (DerivedClass)new ParentClass(); //compiler allows, but runtime gives InvalidCast Exception


*Declaring base class variable as derived class is allowed. 

ParentClass pc = new DerivedClass();

In this case: 

*Derived Object is created and it remains on Heap. 

*However any access to the pc variable always refers to properties or methods of parent class

*EXCEPT for virtual/override combination. 

*Only for overridden methods in this case, the methods of derived class are called. 

*FOR ANY METHODS NOT SATISFYING THE FOLLOWING FOUR CONDITIONS, ALWAYS BASE CLASS IMPLEMENTATIONS ARE CALLED.


THUS TO TRIGGER RUNTIME POLYMORPHISM:

*The method/property in parent class must be declared with "virtual" keyword

*The same method/property in child class must be declared with "override" keyword

*The variable(LHS) must of parent type 

*The object(RHS) must be of child type




MUTLIPLE HIERACRHY: 

Consider the case of Grand Parent, Parent and Child class. We can have

GrandParent gp = new Child(); 


In this case if a method is declared as virtual in GP, and it is overridden ACROSS ALL CLASSES IN 

THE CHAIN, THEN THE CHILD CLASS (RHS CLASS) METHOD IS CALLED. 

BUT IF THE CHAIN IS BROKEN SOMEWHERE BY METHOD HIDING, THE GP (base class on LHS) METHOD IS CALLED.

Note that the only classes in consideration are either RHS or LHS classes, nobody else in the hierarchy.




*Why properties can be declared as virtual and why it is a good practice to override them: 

*Properties are also methods ( getter/setter) hence they are also part of virtual/override logic

*Properties also should be overridden to clear any confusion. Consider the case:

*Base class declares a property as virtual and it declares two methods such that:

- both methods use this property for their calculations

- one of the two methods is virtual and other is not

*Now derived class overrides the virtual method and puts it own logic into it

*BUT derived class redeclares the property and forgets to use "override" keyword.

*Now Base baseClass  = new Derived(); declaration is done. 

*Now the memory representation of baseClass contains two versions of the property: 

*one for base class

*second for derived class, because its redeclaration shadows original base version.

*So the overridden method refers to the property value of derived class

*And the non-overridden method uses the value of property from base class.

THIS IS THE CONFUSION CAUSED. HENCE IT IS ALWAYS A GOOD PRACTIVE TO OVERRIDE VIRTUAL PROPERTIES ALSO.



Consider a hierarchy of multiple classes. Some of them  use override , some of them do not. 

When does the virtual hierarchy ends ? 

*in c#, any overridden method is implicitly virtual. Any override method can again be 

overridden by child class. In this case, the virtual override mechanism always looks for the applicable LAST override in the hierarchy. 




A method is declared as "virtual" in base class. What keywords are allowed for it in derived class ? 

"new" -> suppresses warning "hides the inherited member" 

"virtual" -> hides the parent method, declares new virtual method, warning - "hides the inherited member"

"new virtual" -> hides parent method, declares new virtual method, warning suppressed

"override" -> overrides parent method, "new" or "virtual" are not allowed with this

YOU CANNOT USE "new" or "virtual" in combination with "override" keyword.



isn't it a compile time error to have override without virtual in the base class ?

Yes: It is a compile time error to use override keyword with a method that is not "virtual" in base class. 


When you declare a virtual function:

  • The compiler adds a hidden pointer inside the object → vptr
  • This pointer points to a table of function addresses → vtable



No comments:

Post a Comment

Python List, NumPy Array and Pandas DataFrame

 The strength of numpy arrays is that it allows for vectorized operations (applying a calculation to the whole array at once without loops)...