What is Shadowing?
Asked Answered
C

11

35

In C# what does the term shadowing mean? I have read this link but didn't fully understand it.

Commorancy answered 23/3, 2009 at 15:16 Comment(4)
Not everyone explains things in exactly the same way do they? Wasn't there some teachers in school that you thought where better then others?Commorancy
It should be noted that shadowing is a VB term--C# calls this hiding.Shriner
I've always heard it called it shadowing, in JS, C, JavaAstound
Here's a pretty good video on it. youtube.com/watch?v=xmjOPCnSE30Mallorie
S
45

Shadowing hides a method in a base class. Using the example in the question you linked:

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

Class B overrides the virtual method Bar. It hides (shadows) the non-virtual method Foo. Override uses the override keyword. Shadowing is done with the new keyword.

In the code above, if you didn't use the new keyword when defining the Foo method in class B, you would get this compiler warning:

'test.B.Foo()' hides inherited member 'test.A.Foo()'. Use the new keyword if hiding was intended.
Stereoscope answered 23/3, 2009 at 15:25 Comment(4)
What is functional purpose of this? Like why would you hide something instead of overriding it?Pomfret
@sab669: Imagine you want to "override" a non-virtual method. You can't actually override it, so instead you shadow it. It's not a perfect solution because it doesn't act like an overridden virtual method in all cases, but when called from the derived class, it will work as expected. It's relatively rare that you'd want to do this, but when you need it you really need it.Stereoscope
Ah, so it kind of just exists as a "Well that method isn't virtual, and for one reason or another I can't make it virtual, so new will have to do" kind of thing?Pomfret
@sab669: That's one use. See #1194348 and #14462225 for additional info.Stereoscope
T
32
  • Overriding : redefining an existing method on a base class
  • Shadowing : creating an entirely new method with the same signature as one in a base class
Tensile answered 23/3, 2009 at 15:19 Comment(2)
New method - with the same signature or?Ram
Note that with shadowing you can change the return type.Phyllotaxis
P
21

Suppose I have a base class that implements a virtual method:

public class A
{
    public virtual void M() { Console.WriteLine("In A.M()."); }
}

I also have a derived class that also defines a method M:

public class B : A
{
    // could be either "new" or "override", "new" is default
    public void M() { Console.WriteLine("In B.M()."); }
}

Now, suppose I write a program like this:

A alpha = new B(); // it's really a B but I cast it to an A
alpha.M();

I have two different choices for how I want that to be implemented. The default behavior is to call A's version of M. (This is identical to the behavior if you applied the "new" keyword to B.M().)

This is called "shadowing" when we have a method with the same name but a different behavior when called from the base class.

Alternately, we could have specified "override" on B.M(). In this case, alpha.M() would have called B's version of M.

Poplin answered 23/3, 2009 at 15:24 Comment(0)
I
10

Shadowing consist on hiding a base class method with a new definition in a child class.

The difference between hiding and overriding has to do with the way methods are invoked.

That way, when a virtual method is overridden, the call address for the method call table of the base class is replaced with the address of the child routine.

On the other hand, when a method is hidden, a new address is added to the method call table of the child class.

When a call is made to the method in question:

  1. The method call table class type is obtained, if we are invoking with a reference to the base class then the base class method table is obtained, if we have a reference to the child class, then the child class method table is obtained.
  2. The method is searched in the table, if it's found then the invocation takes place, otherwise the base class method table is searched.

If we invoke the method with a reference to the child class then the behavior is the same, if the method has been overridden, the method address will be found in the base class, if the method was hidden the method address will be found on the child class, and since it has been already found, base class table will not be searched.

If we invoke the method with a reference to the base class then behavior changes. When overriding, as the method address overwrites base class entry, we will call the child method, even when holding a reference to the base class. With shadowing, the base class method table (which is the only one visible as we hold a reference to the base class) contains the virtual method address, and therefore, the base class method will be called.

In general shadowing is a bad idea, as it introduces a difference on the behavior of an instance depending on the reference we have to it.

Individualism answered 23/3, 2009 at 15:39 Comment(0)
M
8

Expanding on Kent's correct answer

When disambiguating when which method will be called, I like to think of shadowing vs. overriding with the following

  • Shadowing: The method called depends on the type of the reference at the point the call is made
  • Overriding: The method called depends on the type of the object at the point the call is made.
Miscreated answered 23/3, 2009 at 15:55 Comment(0)
L
3

Here's an MSDN article on Shadowing. The language examples are in Visual Basic (unfortunately there is no equivalent C# page on MSDN), but it deals generally with the concepts and hopefully should help you understand anyway.

Edit: Seems like there is a C# article on shadowing, except that it's called hiding in C#. Also, this page offers a good overview.

Lituus answered 23/3, 2009 at 15:23 Comment(1)
That's because it's called hiding in C#: msdn.microsoft.com/en-us/library/aa691133(VS.71).aspxShriner
J
2

If you want to hide Base class method , Use override in base [virtual method in base]

if you want to hide Child class method , Use new in base [nonvirtual method in base]->shadow

Base B=new Child()

B.VirtualMethod() -> Calls Child class method

B.NonVirtualMethod() -> Calls Base class method

Josiah answered 11/4, 2012 at 6:49 Comment(0)
R
0

Overriding: same name and exactly the same parameters, implemented differently in sub classes.

  • If treated as DerivedClass or BaseClass, it used derived method.

Shadowing: same name and exactly the same parameters, implemented differently in sub classes.

  • If treated as DerivedClass, it used derived method.
  • if treated as BaseClass, it uses base method.
Radiochemical answered 13/4, 2018 at 1:9 Comment(0)
R
0

Hope this brief explanation helps.

Shadowing - Replaces the complete element of the parent class

class InventoryAndSales
{
    public int InvoiceNumber { get; set; }
}

//if someone calls for this class then the InvoiceNumber type is now object 
class NewInventoryAndSales : InventoryAndSales
{
    public new object InvoiceNumber { get; set; }
}



Overriding - Only replaces the implementation. It doesn't replace the data type it doesn't replace like for example you have a variable it doesn't convert it into a method so if there is a method it will use that method and only changed the implementation

 class InventoryAndSales
    {
        public virtual int GetTotalSales(int a, int b)
        {
            return a + b;
        }
    }


    class NewInventoryAndSales : InventoryAndSales
    {
        //it replaces the implementation in parent class
        public override int GetTotalSales(int a, int b)
        {
            return a * b;
        }
    }
Remy answered 14/6, 2018 at 10:52 Comment(0)
O
-3

Shadowing isn't something I'd be worried about understanding or implementing unless it "fits" the problem really well. I've seen it used improperly and cause weird logic bugs much more often than being used correctly. The big cause, I think, is when the programmer forgets to put overrides in a method signature then the compiler warning will suggest the new keyword. I've always felt that it should recommend using override instead.

Octoroon answered 23/3, 2009 at 15:33 Comment(1)
This feels like a comment.Quadragesima
D
-4
 private static int x = 10;


static void Main(string[] args)
    { int x = 20;
        if (Program.x == 10)
        {
            Console.WriteLine(Program.x);
        }
        Console.WriteLine(x);}

Output:

10 20

Danella answered 11/1, 2012 at 12:56 Comment(1)
This doesn't answer the questionMonolithic

© 2022 - 2024 — McMap. All rights reserved.