C# - Keyword usage virtual+override vs. new
Asked Answered
B

11

228

What are differences between declaring a method in a base type "virtual" and then overriding it in a child type using the "override" keyword as opposed to simply using the "new" keyword when declaring the matching method in the child type?

Banquet answered 1/10, 2008 at 22:6 Comment(3)
MSDN say "Using new creates a new member with the same name and causes the original member to become hidden, while override extends the implementation for an inherited member"Scumble
see this #17718070Sergeant
MSDN - msdn.microsoft.com/en-us/library/ms173153.aspxWelldefined
L
202

The "new" keyword doesn't override, it signifies a new method that has nothing to do with the base class method.

public class Foo
{
     public bool DoSomething() { return false; }
}

public class Bar : Foo
{
     public new bool DoSomething() { return true; }
}

public class Test
{
    public static void Main ()
    {
        Foo test = new Bar ();
        Console.WriteLine (test.DoSomething ());
    }
}

This prints false, if you used override it would have printed true.

(Base code taken from Joseph Daigle)

So, if you are doing real polymorphism you SHOULD ALWAYS OVERRIDE. The only place where you need to use "new" is when the method is not related in any way to the base class version.

Legnica answered 1/10, 2008 at 22:10 Comment(8)
You should revise your code, I had made the methods static (which is valid for using the "new" keyword). But I decided it was clearer to use instance methods.Laquanda
Thank you, i missed the "static" part. Should take more attention on the futureLegnica
Note that the line Foo test = new Bar () is crucial here, the new / override keyword for the metods determine which metod is called when you put a Bar into a Foo variable.Towne
... so it's the exact same as simply not having virtual in the base and override in derived? Why does it exist? The code will still run even w/o new - so is it purely just readability?Perceivable
Your answer dear sir is pretty vague. new and virtual-override do the pretty same thing, the only difference is that new HIDES the method in the parent class and override.. well, overrides it. Of course it prints false because your test object is of type Foo, if it would be of type Bar, it would print true. Pretty tricky example, though.Chemnitz
new keyword on a member field declaration doesn't make much sense to me. I could still call base.Whatever in the function bodyAprilette
The compiler won't let you use override here. There is no virtual method available.Bobbinet
You said "if you are doing real polymorphism you SHOULD ALWAYS OVERRIDE". Please define "real" in this case.Packing
S
254

I always find things like this more easily understood with pictures:

Again, taking joseph daigle's code,

public class Foo
{
     public /*virtual*/ bool DoSomething() { return false; }
}

public class Bar : Foo
{
     public /*override or new*/ bool DoSomething() { return true; }
}

If you then call the code like this:

Foo a = new Bar();
a.DoSomething();

NOTE: The important thing is that our object is actually a Bar, but we are storing it in a variable of type Foo (this is similar to casting it)

Then the result will be as follows, depending on whether you used virtual/override or new when declaring your classes.

Virtual/Override explanation image

Scarecrow answered 1/10, 2008 at 22:41 Comment(2)
Thanks....but could you please explain a little about picture above with regard to the casting you said?Vermifuge
Oops If forgot to add these few line to my prev. comment: do you mean virtual/overriding and non-vitual/new are used just for polymorphysm concept and when you simply declare a variable (not using casting) they don't mean? Thanks again.Vermifuge
L
202

The "new" keyword doesn't override, it signifies a new method that has nothing to do with the base class method.

public class Foo
{
     public bool DoSomething() { return false; }
}

public class Bar : Foo
{
     public new bool DoSomething() { return true; }
}

public class Test
{
    public static void Main ()
    {
        Foo test = new Bar ();
        Console.WriteLine (test.DoSomething ());
    }
}

This prints false, if you used override it would have printed true.

(Base code taken from Joseph Daigle)

So, if you are doing real polymorphism you SHOULD ALWAYS OVERRIDE. The only place where you need to use "new" is when the method is not related in any way to the base class version.

Legnica answered 1/10, 2008 at 22:10 Comment(8)
You should revise your code, I had made the methods static (which is valid for using the "new" keyword). But I decided it was clearer to use instance methods.Laquanda
Thank you, i missed the "static" part. Should take more attention on the futureLegnica
Note that the line Foo test = new Bar () is crucial here, the new / override keyword for the metods determine which metod is called when you put a Bar into a Foo variable.Towne
... so it's the exact same as simply not having virtual in the base and override in derived? Why does it exist? The code will still run even w/o new - so is it purely just readability?Perceivable
Your answer dear sir is pretty vague. new and virtual-override do the pretty same thing, the only difference is that new HIDES the method in the parent class and override.. well, overrides it. Of course it prints false because your test object is of type Foo, if it would be of type Bar, it would print true. Pretty tricky example, though.Chemnitz
new keyword on a member field declaration doesn't make much sense to me. I could still call base.Whatever in the function bodyAprilette
The compiler won't let you use override here. There is no virtual method available.Bobbinet
You said "if you are doing real polymorphism you SHOULD ALWAYS OVERRIDE". Please define "real" in this case.Packing
C
50

Here's some code to understand the difference in the behavior of virtual and non-virtual methods:

class A
{
    public void foo()
    {
        Console.WriteLine("A::foo()");
    }
    public virtual void bar()
    {
        Console.WriteLine("A::bar()");
    }
}

class B : A
{
    public new void foo()
    {
        Console.WriteLine("B::foo()");
    }
    public override void bar()
    {
        Console.WriteLine("B::bar()");
    }
}

class Program
{
    static int Main(string[] args)
    {
        B b = new B();
        A a = b;
        a.foo(); // Prints A::foo
        b.foo(); // Prints B::foo
        a.bar(); // Prints B::bar
        b.bar(); // Prints B::bar
        return 0;
    }
}
Crifasi answered 1/10, 2008 at 22:15 Comment(4)
thank you for this - but why use new to "hide" the base method, when simply not using override seems to do the same?Perceivable
I don't think it was created to prevent the base class from being overriden. I think it was created to avoid name clashing as you can't override a method which is not virtual and the compiler will complain if it sees the same function name on a class "bloodline" with no virtual signatureAprilette
This is a really nice answer. So new basically allows the parent method to remain accessible (when the child is cast/used as the parent type). On the contrary, virtual+override guarantees that the child method is used regardless of how the child is cast/used (only if overriding, of course).Stedfast
@DonCheadle Omitting both "new" and "override" results in a warning so introducing "new" gets rid of the warning.Packing
L
22

The new keyword actually creates a completely new member that only exists on that specific type.

For instance

public class Foo
{
     public bool DoSomething() { return false; }
}

public class Bar : Foo
{
     public new bool DoSomething() { return true; }
}

The method exists on both types. When you use reflection and get the members of type Bar, you will actually find 2 methods called DoSomething() that look exactly the same. By using new you effectively hide the implementation in the base class, so that when classes derive from Bar (in my example) the method call to base.DoSomething() goes to Bar and not Foo.

Laquanda answered 1/10, 2008 at 22:10 Comment(0)
V
13

Beyond just the technical details, I think using virtual/override communicates a lot of semantic information on the design. When you declare a method virtual, you indicate that you expect that implementing classes may want to provide their own, non-default implementations. Omitting this in a base class, likewise, declares the expectation that the default method ought to suffice for all implementing classes. Similarly, one can use abstract declarations to force implementing classes to provide their own implementation. Again, I think this communicates a lot about how the programmer expects the code to be used. If I were writing both the base and implementing classes and found myself using new I'd seriously rethink the decision not to make the method virtual in the parent and declare my intent specifically.

Voluminous answered 1/10, 2008 at 22:20 Comment(1)
The technical explanations of new vs override are sound, but this answer seems to help the most for guiding devs on which to use.Wartburg
P
11

virtual / override tells the compiler that the two methods are related and that in some circumstances when you would think you are calling the first (virtual) method it's actually correct to call the second (overridden) method instead. This is the foundation of polymorphism.

(new SubClass() as BaseClass).VirtualFoo()

Will call the SubClass's overriden VirtualFoo() method.

new tells the compiler that you are adding a method to a derived class with the same name as a method in the base class, but they have no relationship to each other.

(new SubClass() as BaseClass).NewBar()

Will call the BaseClass's NewBar() method, whereas:

(new SubClass()).NewBar()

Will call the SubClass's NewBar() method.

Putrescent answered 1/10, 2008 at 22:24 Comment(0)
F
4

The difference between the override keyword and new keyword is that the former does method overriding and the later does method hiding.

Check out the folllowing links for more information...

MSDN and Other

Fishworm answered 1/10, 2008 at 22:11 Comment(0)
D
3
  • new keyword is for Hiding. - means you are hiding your method at runtime. Output will be based base class method.
  • override for overriding. - means you are invoking your derived class method with the reference of base class. Output will be based on derived class method.
Draughts answered 19/7, 2011 at 6:51 Comment(0)
E
3

My version of explanation comes from using properties to help understand the differences.

override is simple enough, right ? The underlying type overrides the parent's.

new is perhaps the misleading (for me it was). With properties it's easier to understand:

public class Foo
{
    public bool GetSomething => false;
}

public class Bar : Foo
{
    public new bool GetSomething => true;
}

public static void Main(string[] args)
{
    Foo foo = new Bar();
    Console.WriteLine(foo.GetSomething);

    Bar bar = new Bar();
    Console.WriteLine(bar.GetSomething);
}

Using a debugger you can notice that Foo foo has 2 GetSomething properties, as it actually has 2 versions of the property, Foo's and Bar's, and to know which one to use, c# "picks" the property for the current type.

If you wanted to use the Bar's version, you would have used override or use Foo foo instead.

Bar bar has only 1, as it wants completely new behavior for GetSomething.

Eyehole answered 6/9, 2016 at 7:30 Comment(0)
P
2

Not marking a method with anything means: Bind this method using the object's compile type, not runtime type (static binding).

Marking a method with virtual means: Bind this method using the object's runtime type, not compile time type (dynamic binding).

Marking a base class virtual method with override in derived class means: This is the method to be bound using the object's runtime type (dynamic binding).

Marking a base class virtual method with new in derived class means: This is a new method, that has no relation to the one with the same name in the base class and it should be bound using object's compile time type (static binding).

Not marking a base class virtual method in the derived class means: This method is marked as new (static binding).

Marking a method abstract means: This method is virtual, but I will not declare a body for it and its class is also abstract (dynamic binding).

Perspicuous answered 5/12, 2018 at 19:59 Comment(0)
C
2
using System;  
using System.Text;  
  
namespace OverrideAndNew  
{  
    class Program  
    {  
        static void Main(string[] args)  
        {  
            BaseClass bc = new BaseClass();  
            DerivedClass dc = new DerivedClass();  
            BaseClass bcdc = new DerivedClass();  
  
            // The following two calls do what you would expect. They call  
            // the methods that are defined in BaseClass.  
            bc.Method1();  
            bc.Method2();  
            // Output:  
            // Base - Method1  
            // Base - Method2  
  
            // The following two calls do what you would expect. They call  
            // the methods that are defined in DerivedClass.  
            dc.Method1();  
            dc.Method2();  
            // Output:  
            // Derived - Method1  
            // Derived - Method2  
  
            // The following two calls produce different results, depending
            // on whether override (Method1) or new (Method2) is used.  
            bcdc.Method1();  
            bcdc.Method2();  
            // Output:  
            // Derived - Method1  
            // Base - Method2  
        }  
    }  
  
    class BaseClass  
    {  
        public virtual void Method1()  
        {  
            Console.WriteLine("Base - Method1");  
        }  
  
        public virtual void Method2()  
        {  
            Console.WriteLine("Base - Method2");  
        }  
    }  
  
    class DerivedClass : BaseClass  
    {  
        public override void Method1()  
        {  
            Console.WriteLine("Derived - Method1");  
        }  
  
        public new void Method2()  
        {  
            Console.WriteLine("Derived - Method2");  
        }  
    }  
}  
Chara answered 30/6, 2021 at 10:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.