Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How method hiding works in C#? (Part Two)

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?

like image 941
Prankster Avatar asked Apr 02 '09 16:04

Prankster


People also ask

What is hiding a method in C sharp?

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.

What is hiding a method how is it different from overriding C#?

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.

Which of the following method can be used to hide the keyword?

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.

Can we hide virtual method in C#?

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.


1 Answers

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.

like image 159
Jon Skeet Avatar answered Oct 09 '22 13:10

Jon Skeet