Difference between shadowing and overriding in C#?
Asked Answered
M

7

110

What's difference between shadowing and overriding a method in C#?

Manducate answered 25/12, 2008 at 10:45 Comment(0)
C
164

Well inheritance...

suppose you have this classes:

class A {
   public int Foo(){ return 5;}
   public virtual int Bar(){return 5;}
}
class B : A{
   public new int Foo() { return 1;}     //shadow
   public override int Bar() {return 1;} //override
}

then when you call this:

A clA = new A();
B clB = new B();

Console.WriteLine(clA.Foo()); // output 5
Console.WriteLine(clA.Bar()); // output 5
Console.WriteLine(clB.Foo()); // output 1
Console.WriteLine(clB.Bar()); // output 1

//now let's cast B to an A class
Console.WriteLine(((A)clB).Foo()); // output 5 <<<-- shadow
Console.WriteLine(((A)clB).Bar()); // output 1

Suppose you have a base class and you use the base class in all your code instead of the inherited classes, and you use shadow, it will return the values the base class returns instead of following the inheritance tree of the real type of the object.

Run code here

Hope I'm making sense :)

Cavanagh answered 25/12, 2008 at 10:55 Comment(12)
Overriding provides polymorphism, shadowing provides a different implementation at that level of the hierarchy, but not polymorphically.Craver
@dribeas, What definition of polymorphism would you be using to draw that conclusion?Multitude
@AnthonyWJones, Polymorphism is the ability of one (derived) type to be used as a different (base) type where the real implementation (behavior) is that of the real specific (derived) type. If you override, derived method will be called through reference to base, but if you shadow that is not trueCraver
@dribeas: That would be the definition from the classic "Three-pillar" school of OO. However polymorphism happens where any chunk of code may result in different behaviour depending on the types involved. c = a + b is polymorphic yet doesn't depend on virtual implementations.Multitude
Seems to me, you have an error in your sample code. The casting should be ((A)clB).Foo(), shouldn't it?Thick
Console.WriteLine(((A)clB).Bar()); // output 1 <=== should be: Console.WriteLine(((A)clB).Bar()); // output 5 <=== class A returns 5'sGall
No, because bar is virtual, so it will still call the B BarCavanagh
Best answer I have gotten on Shadowing vs Overriding.Panchito
Maybe we should add an example of "overloading" to this as well.Aviate
An overload is method that is distinguishable by its parameter type signature. A shadow (new) can be seen as an overload that hides a virtual.Aviate
Could you please explain what will the behavior if we use public int Foo in derived class instead of public new int Foo()Backchat
@SethuBala, the behavior will be the same, it will still shadow the function, the compiler will give you a warning about it: warning CS0108: 'B.Foo()' hides inherited member 'A.Foo()'. Use the new keyword if hiding was intended.Cavanagh
M
34

Shadowing is actually VB parlance for what we would refer to as hiding in C#.

Often hiding (shadowing in VB) and overriding are shown as in answer by Stormenet.

A virtual method is shown to be overridden by a sub-class and calls to that method even on the super-class type or from inside code of the super-class will call the replacement implementation from the sub-class.

Then a concrete method is shown (one not marked as virtual or abstract) being hidden by using the new keyword when defining a method with an identical signature on the sub-class. In this case when the method is called on the super-class type the original implementation is used, the new implementation is only available on the sub-class.

However what is often missed is that it is also possible to hide a virtual method.

class A
{
    public virtual void DoStuff() { // original implementation }
}

class B : A
{
    public new void DoStuff() {  //new implementation }
}

B b = new B();
A a = b;

b.DoStuff(); //calls new implementation
a.DoStuff(); //calls original implementation.

Note in the above example DoStuff becomes concrete and can not be overriden. However it is also possible to use both the virtual and new keywords together.

class A
{
    public virtual void DoStuff() { // original implementation }
}

class B : A
{
    public new virtual void DoStuff() {  //new implementation }
}

class C : B
{
    public override void DoStuff() { //replacement implementation }
}

C c = new C();
B b = c;
A a = b;

c.DoStuff(); //calls replacement implementation
b.DoStuff(); //calls replacement implementation
a.DoStuff(); //calls original implementation.

Note that despite all the methods involved being virtual, the override on C does not affect the virtual method on A because of the use of new in B hides the A implementation.

Edit: Its been noted in the comments to this answer that the above may be dangerous or at least not particularly useful. I would say yes it can be dangerous and would be out there if it were at all useful.

In particular you could get into all sorts of trouble if you also change the accessability modifiers. For example:-

public class Foo
{
    internal Foo() { }
    protected virtual string Thing() { return "foo"; }
}

public class Bar : Foo
{
 internal new string Thing() { return "bar"; }
}

To an external inheritor of Bar, Foo's implementation of Thing() remains accesible and overridable. All legal and explainable according to .NET type rules neverless quite unintuative.

I've posted this answer to deepen an understanding of how things work not as a suggestion of techniques that can be used freely.

Multitude answered 25/12, 2008 at 12:21 Comment(5)
Nice to know that. Altough it's use can be dangerous :)Cavanagh
All tools can be dangerous when not used properly.Multitude
But, it's usability really seems questionable! Is there any 'serious' open-source app using this?Manducate
Usability? Do you mean usefulness? Somethings that are on the fringe may seem useless right up until you need them.Multitude
It seems that Shadowing comes into picture ONLY when virtual and new plays. @Stormenet's is explaining only override thing because it is normal behaviour of class to call its own method unless it is virtual.Pirog
C
6

I think the main difference is that with shadowing, you're essentially reusing the name, and just ignoring the superclass use. With overriding, you're changing the implementation, but not the accessibility and signature (e.g. parameter types and return). See http://www.geekinterview.com/question_details/19331 .

Coraleecoralie answered 25/12, 2008 at 10:52 Comment(0)
M
5

Shadowing is a VB.NET concept. In C#, Shadowing is known as Hiding. It hides the derived class method. It is accomplished using the ‘new’ keyword.

Override keyword is used to provide a completely new implementation of a base class method (which is marked ‘Virtual’) in the derived class.

Medawar answered 2/3, 2014 at 9:37 Comment(1)
You mean. It hides the derived class method instead uses the base class method. ?Henninger
W
1

The answers above do not describe how to shadow/hide a base class' constructor. For completeness adding that special case here.

Say if you want to wrap ApplicationException in your own class MyApplicationException here is the syntax....

public class MyApplicationException : ApplicationException
{
    public MyApplicationException(string message) : base(message)
    {
        // NOOP
    } // constructor

    public MyApplicationException(string message, Exception innerException) : base(message, innerException)
    {
        // NOOP
    } // constructor
} // class MyApplicationException
Wad answered 23/2, 2023 at 14:41 Comment(0)
Y
0

Basically if you have something like below,

Class A
{
}

Class B:A
{
}

A a = new B();

Any method you call on the object 'a' will be made on the type of 'a'(Here the type is 'A') But if you implement the same method in class B that is already present in Class A, the compiler will give you a warning to use a "New" keyword. If you use "New", the warning will disappear. Other than this there is no difference between using "New" or not using it in the inherited class.

In some situations you may need to call a method of the reference class the particular instance holds at that moment instead of calling a method on the object type. In the above case the reference it holds is 'B', but the type is 'A'. So if you want the method call should happen on 'B', then you use Virtual and override to achieve this.

Hope this helps...

Daniel Sandeep.

Yerxa answered 6/10, 2011 at 11:1 Comment(0)
P
0

If there is a case in which you cannot alter the contents of a class, let's say A, but you want to use its some methods along with you have a method which name is common, you can use your own method implementation by the new keyword.

The crux point is to use it that both the reference and object must be of the same type.

class A
{
    public void Test()
    {
        Console.WriteLine("base");
    }
}

class B : A
{
    public new void Test()
    {
        Console.WriteLine("sub");
    }

    public static void Main(string[] args)
    {
        A a = new A();
        B aa = new B();
        a.Test();
        aa.Test();
    }
}
Pursuant answered 26/3, 2020 at 19:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.