I have simple three classes:
class A
{
public virtual void Write()
{
Console.Write("A");
}
}
class B:A
{
public override void Write()
{
Console.Write("B");
}
}
class C : B
{
public new void Write()
{
Console.Write("C");
}
}
And I am creating objects and calling their methods:
A a = new A();
a.Write();
A b = new C();
b.Write();
C c = new C();
c.Write();
And output will be: ABC
What I cannot understand is why these code produces B
?:
A b = new C();
b.Write();
I thought that it should be C
. However, I tested many times, and it is always B
.
I understand that A b = new C()
creates new object type of C. So output should be C. Or it is special behavior to call overridden method when we use it without casting?
Why does it happen? As we have not used any reference to B
class.
If the method in the derived class is preceded with the new keyword, the method is defined as being independent of the method in the base class.
Use the new keyword to create an instance of the array. The new operator is used to create an object or instantiate an object. Here in the example an object is created for the class using the new.
The base class method can be called from within the derived class using the base keyword. The override , virtual , and new keywords can also be applied to properties, indexers, and events.
The override modifier extends the base class virtual method, and the new modifier hides an accessible base class method. The difference is illustrated in the examples in this topic. In a console application, declare the following two classes, BaseClass and DerivedClass .
It would work if you'd use ((C)b).Write();
With the new
keyword you're not overriding the Write
method for C but rather creating a new method only defined for C. So for your C you actually have 2 methods with a method name Write
.
A c = new C();
c.Write(); //Output "B", you're calling the overridden method
((C)c).Write(); //Output "C", you're calling the method defined on C
//or
(c as C).Write();
The same happens when you would define c as C
:
C c = new C();
c.Write(); //Output "C"
((A)c).Write(); //Output "B"
In the first example you're calling the new method defined on C. In the second line you are calling the Write
method from A, which is overridden by B, hence the output "B"
.
Edit: (some more explanation)
Variable c
is of type A, so that's what your compiler knows "c is an instance of A", it is not known that it is actually of a more derived type. When you call the method Write
on it, it will invoke the method defined on A (which is overriden by B). Your base class A has no knowledge of your new method defined on C (that's what new
does, create a new method), so unless you cast it to C to let the compiler know about the actual, derived type of c
, the method of your base class will be called.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With