Mladen Prajdić Blog

Blog about stuff and things and stuff. Mostly about SQL server and .Net

How to Override Non-Virtual Base Members in C#

This is something i assumed was common knowledge, but apparently it isn't.

If you want to have a method in your derived class with the same name as the one in the base class and the base class one isn't marked

as virtual you can use the NEW keyword.

This is also the default behaviour and the compiler treats the child class method as new, however you get a warning for this.

 

Some code to illustrate this:

 

public class BaseClass
{
    public BaseClass()
    { }
<span class="kwrd">public</span> <span class="kwrd">void</span> IAmANonVirtualMethod()
{
    Console.WriteLine(<span class="str">&#34;IAmANonVirtualMethod in BaseClass.&#34;</span>);
}

<span class="kwrd">public</span> <span class="kwrd">virtual</span> <span class="kwrd">void</span> IAmAVirtualMethod()
{
    Console.WriteLine(<span class="str">&#34;IAmAVirtualMethod in BaseClass.&#34;</span>);
}

}

public class ChildClass : BaseClass { public ChildClass() { }

<span class="kwrd">public</span> <span class="kwrd">new</span> <span class="kwrd">void</span> IAmANonVirtualMethod()
{
    Console.WriteLine(<span class="str">&#34;IAmANonVirtualMethod in ChildClass.&#34;</span>);
}

}

BaseClass bc = new BaseClass(); ChildClass cc = new ChildClass(); bc.IAmANonVirtualMethod(); cc.IAmANonVirtualMethod(); bc.IAmAVirtualMethod(); cc.IAmAVirtualMethod();

/* Output IAmANonVirtualMethod in BaseClass. IAmANonVirtualMethod in ChildClass. IAmAVirtualMethod in BaseClass. IAmAVirtualMethod in BaseClass. */

Legacy Comments


Ray
2007-04-09
re: How to Override Non-Virtual Base Members in C#
Carefull with this though it might not work as advertised here, when the base class calls the function overriden with the new keyword its selve the implementation in the baseclass is called not the implementation in the childclass.

When you add

public void CallMethods()
{
IAmANonVirtualMethod();
IAmAVirtualMethod();
}

That function to the baseclass and call it on both in the main function you'll see that the implementation overriden in the child class is never called.


Andrej Tozon
2007-04-10
re: How to Override Non-Virtual Base Members in C#
Using the "new" keyword is not same as overriding... "new" just *adds* additional method (with the same name) to the derived class, whereas overriding a virtual method actually overrides it. Using "new" keyword may sometimes lead to confusing situations - try the following code lines with your classes:

ChildClass cc = new ChildClass();
BaseClass bcc = new ChildClass();
cc.IAmANonVirtualMethod();
bcc.IAmANonVirtualMethod();

Mladen
2007-04-10
re: How to Override Non-Virtual Base Members in C#
@Ray:
Of course it's not.
As Andrej pointed out it's a new method in the base class.

@Andrej:
have you ever had to acctually use this form:
BaseClass bcc = new ChildClass();
I really hate writing code like that. :))


Andrej Tozon
2007-04-10
re: How to Override Non-Virtual Base Members in C#
Mladen - yes, I do it all the time... not necessariliy in the form I previously posted, but consider this (somehow silly) example for illustration:

Classes:

public class Dog
{
public void Bark()
{
Console.WriteLine("Growl!");
}
}

public class Puppy : Dog
{
public new void Bark()
{
Console.Write("Woof!");
}
}


Calling class:

static class Program
{
[STAThread]
static void Main()
{
Dog dog = new Dog();
MakeHimBark(dog);

Puppy puppy = new Puppy();
MakeHimBark(puppy);
}

public static void MakeHimBark(Dog theDog)
{
theDog.Bark();
}
}

The output, of course is - 2x Growl, even when I instantiated Puppy as a puppy. However, overriding Bark method in Puppy class (if it was marked virtual), would give expected result (Growl, Woof).

Jesse
2007-04-10
re: How to Override Non-Virtual Base Members in C#
"have you ever had to acctually use this form:
BaseClass bcc = new ChildClass();
I really hate writing code like that. :))"

that's what polymorphism is all about. if you hate it, you hate a pretty major aspect of OOP. :)


Mladen
2007-04-11
re: How to Override Non-Virtual Base Members in C#
ok so why couldn't you just write:
ChildClass bcc = new ChildClass();
instead of:
BaseClass bcc = new ChildClass();

ok i guess there are moments where this is usefull, but i see no advantage
of 2nd vs the 1st.

Miha Markic
2007-04-11
re: How to Override Non-Virtual Base Members in C#
The difference is that later version can host an instance of any BaseClass derived class while the former can host only ChildClass (derived) class.
Imagine that your instance type is unknown at design time (perhaps based on user choice). All you know is that it will be a instance of BaseClass derived class. You'll want to declare such variable as of BaseClass type.
However, if you are certain that you'll have a ChildClass instance only (or its derived class instance) then your are better with the former.

Andrej Tozon
2007-04-12
re: How to Override Non-Virtual Base Members in C#
"... but i see no advantage..."

This is not about advantage, it's about possibilities. In my Dog/Puppy example above, the MakeHimBark method will accept any Dog class (base Dog or *any* derived class), knowing that each and every one will have the Bark method implemented. The same goes when you're instancing objects at run-time and/or casting them into BaseClass (Dog). Good example of this is some kind of a plug-in framework, where all plug-ins derive from the same type.
The bottom line is, that using "new" may sometimes lead to unpredictible results for developer if he's not familiar with how such implementation behaves at run-time...

Mladen
2007-04-12
re: How to Override Non-Virtual Base Members in C#
ok i must cover myself with dust since i've used exactly this scenario in my latest pet project :))

Your bottom line is correct and agreeable Mr. MVP :))

Tobey
2007-12-20
re: How to Override Non-Virtual Base Members in C#
What I'm getting out of this thread is that the title of this post is incorrect; there is no way to "override" a non-virtual base class method. Said another way, there's no way to get polymorphic behavior on a method if the base class method was not declared as virtual. Is this correct?

Mladen
2007-12-20
re: How to Override Non-Virtual Base Members in C#
yes.

Jonas
2009-03-25
re: How to Override Non-Virtual Base Members in C#
You can "override" non virtual members IF those are part of an interface, by Inheriting AND implementing the interface using the new keyword. But you are really "overriding" the interface method.

public class UniqueList<T> : List<T>, IList<T>
{
public new void Add( T item )
{
if( base.Contains(item) )
{
throw new ArgumentException("non unique");
}
base.Add( item );
}
}

/Jonas

Roman
2009-07-13
re: How to Override Non-Virtual Base Members in C#
Followed code segment has the same behavior with or without IDictionary Interface

namespace VirtualTst
{
public enum IndexTypes{
ruge = 0,
coarse = 1,
comp = 3
}
public class Derived : Dictionary&amp;lt;IndexTypes,int&amp;gt;,IDictionary&amp;lt;IndexTypes,int&amp;gt;
{
public new void Add(IndexTypes IndexType, int Value)
{
Console.WriteLine(&amp;quot;Derived&amp;quot;);
base.Add(IndexType,Value);
}
}
class Class1
{
public static void Main(string[] args)
{
Derived d = new Derived();
d.Add(IndexTypes.coarse, 3);
Dictionary&amp;lt;IndexTypes,int&amp;gt;b = d;
Console.WriteLine(&amp;quot;Try cast to Dictionary&amp;quot;);
b.Add(IndexTypes.ruge, 3);
}
}
}

Any suggestions to fix it?

Lucy
2009-09-10
re: How to Override Non-Virtual Base Members in C#
public class clsAddEditSalary : clsMainAbstract
{
public clsAddEditSalary()
{
//
// TODO: Add constructor logic here
//
}
public override int Display(int j)
{
return j;
}
public override int Display1(int j)
{
return j;
}
public new int Display2(int j)
{
return j;
}
}


public abstract class clsMainAbstract
{
public clsMainAbstract()
{
//
// TODO: Add constructor logic here
//
}
public abstract int Display(int j);
public virtual int Display1(int j)
{
return j + 2;
}
public int Display2(int j)
{
return j + 2;
}
}

clsMainAbstract objAbs = new clsAddEditSalary();
objAbs.Display(9);>>9
objAbs.Display1(10);>>10
objAbs.Display2(11);>>13
clsAddEditSalary objInh = new clsAddEditSalary();
objInh.Display(12);>>12
objInh.Display1(13);>>13
objInh.Display2(14);>>14

Can Some body explain how the output is coming?

Regards,
Lucy