The following program prints
A:C(A,B)
B:C(A,B)
(as it should)
public interface I
{
string A();
}
public class C : I
{
public string A()
{
return "A";
}
public string B()
{
return "B";
}
}
public class A
{
public virtual void Print(C c)
{
Console.WriteLine("A:C(" + c.A() + "," + c.B() + ")");
}
}
public class B : A
{
public new void Print(C c)
{
Console.WriteLine("B:C(" + c.A() + "," + c.B() + ")");
}
public void Print(I i)
{
Console.WriteLine("B:I(" + i.A() + ")");
}
}
class Program
{
public static void Main(string[] args)
{
A a = new A();
B b = new B();
C c = new C();
a.Print(c);
b.Print(c);
}
}
however, if I change keyword 'new' to 'override' in class B like so:
public override void Print(C c)
all of a sudden program starts to print:
A:C(A,B)
B:I(A)
Why?
Method hiding is also known as shadowing. The method of the parent class is available to the child class without using the override keyword in shadowing. The child class has its own version of the same function. Use the new keyword to perform shadowing.
Hiding redefines the complete method, whereas overriding redefines only the implementation of the method. In Overriding, you can access the base class using the child class' object overridden method.. Shadowing has cannot access the child class methods.
The "new" keyword is used to hide a method, property, indexer, or event of the base class into the derived class. If a method is not overriding the derived method then it is hiding it. A hiding method must be declared using the new keyword.
Well, this is not possible, because the base class method will still be visible. Because MyClass is a LinkButton , so whatever is allowed with LinkButton , must be allowed with MyClass as well.
This is to do with how overloaded methods are resolved.
Effectively (simplified somewhat), the compiler first looks at the declared type of the expression (B) in this case and looks for candidate methods which are first declared in that type. If there are any methods which are appropriate (i.e. where all the arguments can be converted to the method's parameter types) then it doesn't look at any parent types. This means that overridden methods, where the initial declaration is in a parent type, don't get a look-in if there are any "freshly declared" appropriate methods in the derived type.
Here's a slightly simpler example:
using System;
class Base
{
public virtual void Foo(int x)
{
Console.WriteLine("Base.Foo(int)");
}
}
class Derived : Base
{
public override void Foo(int x)
{
Console.WriteLine("Derived.Foo(int)");
}
public void Foo(double d)
{
Console.WriteLine("Derived.Foo(double)");
}
}
class Test
{
static void Main()
{
Derived d = new Derived();
d.Foo(10);
}
}
This prints Derived.Foo(double)
- even though the compiler knows there is a matching method with a parameter of type int
, and the argument is type int
, and the conversion from int
to int
is "better" than the conversion from int
to double
, the fact that only the Foo(double)
method is originally declared in Derived
means the compiler ignores Foo(int)
.
This is highly surprising IMO. I can see why it would be the case if Derived
didn't override Foo
- otherwise introducing a new, more specific, method in the base class could change the behaviour unexpectedly - but clearly Derived
here knows about Base.Foo(int)
as it's overriding it. This is one of the (relatively few) points where I believe the C# designers made the wrong decision.
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