In C# what does the term shadowing mean? I have read this link but didn't fully understand it.
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.
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
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.
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:
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.
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.
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.
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.
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
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.
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;
}
}
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.
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
Related
If we have this class:
public class a{
public void b(){ Console.WriteLine("a"); }
}
And then this class:
public class c : a{
public override void b(){ Console.WriteLine("c"); }
}
If I do this:
a _a = new c();
_a.b();
What will happen? Which method will be called? The one from base type, or the overridden one?
What will happen? Which method will be called? The one from base type,
or the overridden one?
Firstly, you're not overriding the method b within class a from the class c because you haven't marked it as virtual (should give you a compile time error if you had tried it). However, if you mark the method within class a as virtual like below:
public class a
{
public virtual void b() { Console.WriteLine("a"); }
}
then the result that will be printed out will be "c". The reason is due to the overriding mechanism.
It is an error, the base class's method must be marked virtual, abstract or override.
In the event you add abstract or virtual to the base class's method in your example an call as you did, the overridden method will be executed -- that is the entire point of override.
If you don't want the base class's method to be virtual or abstract, you can use new on the subclass's method and it will be replaced, but not overridden. That is, the method b() of the class the reference _a is cast to will be executed, In your example, it would be method b on class a that would be executed.
There are three ways you can "reuse" a method.
Overriding a method requires that method to be marked abstract or virtual. When overriding a method the overridden method will be called no matter what. You can however call the base method like :
base.Method();
Overloading allows you to change the type and number of Parameters your method uses. So:
public int Method(int A);
can be overloaded as:
public int Method(double B);
Lastly you have new. This allows you to replace a Method in a derived class. If you have a method:
public int Method();
in a base class and you create a new method
public new int Method();
in a derived class your new method will be called in your derived class but the base classes method will be called if you cast your class back to the base class. Not a very clear explaination I know but I am short on time at the moment.
Hope this helps
Danny
I have been told that, a protected variable in the base class can be accessed in the derived class either using base or this keyword. I am totally confused now, because, this keyword refers to the current class (derived class).
public class A
{
protected int i;
}
public class B :A
{
void Display()
{
this.i=10;
// (or)
base.i=10;
}
}
Is there any technical difference ? First of all, today I am pondered to see why I cannot create an object of A inside Display() method and access the variable i through that object as the very definition of protected access says that, it can be accessed in any derived class. Folks, I have seen some threads, however what they say is, we cannot create object and access the protected members. I feel, this is pretty contrary to the definition.
Could someone can please explain me both of my above questions
It's pretty simple:
this refers to the current object (EG, if a method is like void mymethod(int myvar), and the class has myvar defined in it, you can use myvar to refer to the argument, and this.myvar to refer to the the one in the class.)
base refers to the base class (The class your class is derived from). (EG, if you're overwriting a method Update, at the end of it, you can then call base.Update(); to call the original method.)
Let's B extend A class, so, B inherite i of A:
public class A {
protected int i;
}
public class B : A {
void Display() {
i = 10; // this.i
}
}
(again annoying question...)
after asking this before - ( which is partly related to my question) - i got an answer :
See ยง7.6.5.1 of the C# 4 spec:
The set of candidate methods is reduced to contain only methods from
the most derived types: For each method C.F in the set, where C is the
type in which the method F is declared, all methods declared in a base
type of C are removed from the set.
ok.
i have this code : //.Dump() is like a WriteLine command...
public class Base
{
public void Foo(string strings) { "1".Dump();}
public virtual void Foo(object strings) { "2".Dump();}
}
public class Child : Base
{
public override void Foo(object strings) { "4".Dump();}
}
but this code :
Child c = new Child();
c.Foo("d");
emits : "1"
but wait ...
didnt we say that is reduced to contain only methods from the most derived types: ?
Child has 1 function from its father public void Foo(string strings) and a NEARER override function.
so why did he choose its base's function ? does the inherited function is CLOSER than the override ?
is it related to the fact that override is at runtime ?
help please.
edit
what about this situation ?
public class Base
{
public virtual void Foo(int x) { "1".Dump();}
}
public class Child : Base
{
public override void Foo(int x) { "2".Dump();}
public void Foo(object x) { "3".Dump();}
}
void Main()
{
Child c = new Child();
c.Foo(6); //emits "3"
}
That's because your child takes an object.
public class Child : Base
{
public override void Foo(object strings) { "4".Dump();}
}
Make it string and then child one will be called.
public class Child : Base
{
public override void Foo(string strings) { "4".Dump();}
}
Why this?
Because compiler sees that child has object prameter it has to convert to string while in base class it is readily available as string.
So it calls base one.
Though Overridden function is nearer in the child class. But here rules are different in child and base. Child has object and base has string. It was fair if both had object or both had string.
I read this in Jon Skeet's C# in Depth Overloading Section
There are two concepts here which are being confused, overloading and overriding. Overloading is the concept of having multiple signatures for a function of the same name and choosing one to call based on that signature. Overriding is the concept of re-defining a method in a derived class.
Whether or not the child class overrode one of the method definitions does not matter at all to which function will be called because it does not change the signature of either method. By definition and construction overriding a method cannot change it's signature.
So, if the signature is unchanged exactly the same mechanics for determining the correct function to call based on the signature will be used against both the parent and child classes.
Update
In fact there is a little bit more to it as Eric Lippert points out in his blog. It turns out in fact that if there is a method that matches the overload in the child class it will not look for any methods in base classes. The reasons are sane - avoiding breaking changes - but the result is somewhat illogical when you own both the base and child class.
I can only echo Jon Skeet: "Given this oddness, my advice would be to avoid overloading across inheritance boundaries... at least with methods where more than one method could be applicable for a given call if you flattened the hierarchy"
You see here best match rule .
You pass a string like an argument to a Foo(..) function.
Base class has a Foo(string..), Child class, instead, has not. So the method of base is picked eventually , in this case.
I think here the base class method is chosen based on its dataType
As c.Foo("d"); matches exactly to the base class method and there is not any method overridden for it in the derived class therefore the base class method is called.
when use new virtual key words to decorate the method? what is the affection? Like define an interface, and add a class to inherit the interface. but use the new virtual to realize the interface method.
interface IPrinter
{
void Print();
}
public class PrinterOne : IPrinter
{
public void Print()
{
Console.WriteLine("PrinterOne.");
}
}
public class PrinterTwo : PrinterOne
{
public new virtual void Print()
{
Console.WriteLine("PrinterTwo.");
}
}
public class PrinterThree : PrinterTwo
{
public override void Print()
{
Console.WriteLine("PrinterThree.");
}
}
public class PrinterFour : PrinterThree
{
public override void Print()
{
Console.WriteLine("PrinterFour.");
}
}
static void Main(string[] args)
{
IPrinter iprinter = new PrinterFour();
iprinter.Print();//the output is PrinterOne? why???
Console.ReadLine();
}
new and virtual are two (mostly-) unrelated keywords.
new means it shadows the base method.
virtual allows subclasses to override it.
Calling the method through the interface results in the base method being called, since the base method is not virtual and the derived classes don't explicitly re-implement the interface (which would cause the method to be re-mapped)
The new keyword used like this is member hiding.
I have never seen it used in conjunction with the virtual keyword, mind you. It is simply allowing types that derive from PrinterTwo to override the Print method implementation.
The new keyword used this way allows a type to hide the members of base types, but only if you are using a variable of the type itself.
For example, if you were to do:
PrinterOne one = new PrinterTwo();
one.Print();
It would not call the method in PrinterTwo as it is not part of the inheritance chain.
As for when you would do this... when you really, really need to for some odd reason that I can't think of (reflection maybe?) and you cannot edit the code in PrinterOne.
Personally, I wouldn't ever do this.
As for why the output is printer one... calling IPrinter.Print will call against the type it is defined on (PrinterOne in this case), which will put you back in my above example about the new keyword being ignored unless you talk to the type that features it.
Basically, using IPrinter is analogous to using PrinterOne in my small example above.
To solve the problem, make the PrinterOne method virtual and completely remove the use of new virtual in PrinterTwo.
new modifier
http://msdn.microsoft.com/en-us/library/435f1dw2.aspx
When used as a modifier, the new keyword explicitly hides a member inherited from a base class.
This means that the method does not override the virtual base class method, but it still takes precedence when called on an instance of the derived class. In other words, the new method only affects a variable of the derived class, not the base class.
virtual modifier
http://msdn.microsoft.com/en-us/library/9fkccyh4.aspx
The virtual keyword is used to modify a method, property, indexer, or event declaration and allow for it to be overridden in a derived class.
This means that the method can be overriden in a derived class. When you call a virtual method on a base class variable which holds an instance of the derived class that has overridden the virtual method, the derived class implementation is called. This is the opposite of the behaviour of the new keyword.
This is called method hiding. You use this when you need to provide your own implementation for a method that cannot be overridden. Because PrinterOne.Print is not a virtual method, it cannot be overridden. Instead, the new keyword is used to create a identical method signature that hides the original method. The new method will be used instead. Adding the virtual keyword to this, allows your new method to be overridden by deriving classes.
Your new method that hides the original will only be invoked if you call it through the defining container (eg. PrintTwo). Calling it by the interface calls the original method. Mind you, that the method was never removed or replaced so the original implementation still exists by accessing the interface directly.
I was reviewing some code today and came across some code (accurately portrayed by this snippet)...
public abstract class FlargBase{
public FlargBase(){
this.DoSomething();
}
public abstract void DoSomething();
}
public class PurpleFlarg: FlargBase{
public PurpleFlarg()
: base(){
}
public override void DoSomething(){
// Do something here;
}
}
The compiler gives no errors or warnings, but CodeAnalysis warns that the call chain contains a call to a virtual method and may produce unintended results.
I was curious because, as I see it, two things can happen.
Creating an instance of the base class will make a call to a method with no defined implementation. I would expect the compiler to error, or the runtime to throw an exception due to a missing implementation. I'm assuming the compiler is providing an implementation of {} I mis-typed the original code; it did contain the abstract keyword on the class.
Creating an instance of a derived class will cause a call to a method on a class that has not actually been constructed yet. I would have expected this to throw an exception.
This code has been in a production environment for several months. It is apparently working correctly enough that no one has noticed any strange behavior.
I'm hoping the incredible talent here at StackOverflow can give me some insight into the behavior and consequences of this code.
A C# object is fully constructed and initialized to zero before the first constructor runs. The base constructor will call the derived implementation of the virtual method.
It's considered bad style to do this, because the derived implementation might behave strangely when the constructor of the derived class has not been called yet. But the behavior by itself is well defined. If you do nothing in the derived implementation that requires the code from the constructor to have already run, it will work.
You can image that the runtime calls the most derived constructor first. And its first action is to implicitly call the base constructor. I'm not sure if it's actually implemented like that, but since some .net languages allow you to call the base constructor at an arbitrary point of the derived constructor, I expect C# to simply call the base class constructor as first action of the derived constructor.
This behavior is very different from how C++ handles it. In C++ the derived classes get constructed one after the other, and before the constructor of the derived class has started the object has still the type of the baseclass and the overrides from the derived class are ignored.
Your PurpleFlarg.DoSomething() is executed before the PurpleFlarg() constructor body.
That can lead to surprises as the general assumption always is that the constructor is the first method to operate on an object.
Here is the MSDN page with an example of an 'error' condition.
In C#, override methods always resolve to the most derived implementation. An example is given in 10.11.3 (Constructor execution) of the C# spec here:
Variable initializers are transformed into assignment statements, and
these assignment statements are executed before the invocation of the
base class instance constructor. This ordering ensures that all
instance fields are initialized by their variable initializers before
any statements that have access to that instance are executed.
Given the example
using System;
class A
{
public A() {
PrintFields();
}
public virtual void PrintFields() {}
}
class B: A
{
int x = 1;
int y;
public B() {
y = -1;
}
public override void PrintFields() {
Console.WriteLine("x = {0}, y = {1}", x, y);
}
}
when new B() is used to create an instance of B, the following output
is produced:
x = 1, y = 0
If the class contains an abstract method (DoSomething), then the class has to be abstract too and cannot be instantiated.
Well, this pattern is really useful for overridable factories of objects in reality, so a case like the one in the next code seems to me perfectly legal and well written.
abstract class MyBase
{
public object CustomObject { get; private set; }
public MyBase()
{
this.CustomObject = this.CreateCustomObject();
}
protected abstract object CreateCustomObject();
}
class MyBaseList : MyBase
{
protected override object CreateCustomObject()
{
return new List<int>();
}
}
class MyBaseDict : MyBase
{
protected override object CreateCustomObject()
{
return new Dictionary<int, int>();
}
}