C# Name Hiding

In this section, name hiding refers to hide base class members if the names of the members are the same as that in the derived class. The members can be constants, fields, properties, events, types, methods and indexers, etc. Some of them will be introduced later in the tutorial.

Example 01-55-01

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
using System;

namespace TestNameHiding
{
    public class A
    {
        public int i = 1;
        public int j = 2;

        public void test()
        {
            Console.WriteLine("A class");
        }
    }

    public class B : A
    {
        public int j = 3;

        public void test()
        {
            Console.WriteLine("B class");
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            A a = new A();
            Console.WriteLine("i={0}, j={1}", a.i, a.j);    // Output i=1, j=2
            a.test();                                       // Output A class
            B b = new B();
            Console.WriteLine("i={0}, j={1}", b.i, b.j);    // Output i=1, j=3
            b.test();                                       // Output B class
            Console.Read();
        }
    }
}

Output

i=1, j=2
A class
i=1, j=3
B class
  • Line 5-14: Define a public class A including 2 integer fields i, j and a void method test().
  • Line 16-24: Define a derived class B inheriting from A.
  • Line 18: Define an integer field j with the same name in A. It will hide the j field in A.
  • Line 20-23: Define a method test() with the exactly same name in A. Definitely it will hide the test() method in A.
  • Line 26-38: Testing class Program with Main method.
  • Line 30-32: Create an instance of class A and output the values of the fields and run the method test() as usual.
  • Line 33: Instantiate class B.
  • Line 34: Output the values of the fields. Pay attention, this line outputs j=3 which hide the j=2 defined in the base class A.
  • Line 35: Run the test() method and output "B class" instead of "A class".

If the method test() in line 20-23 is removed, what is the result of line 35 ?

The answer is that it will output "A class" because the method test() will be inherited from class A.

The following warning message will be shown up if you try to compile the above code.

TestNameHiding.B.test()' hides inherited member 'TestNameHiding.A.test()'. Use the new keyword if hiding was intended.
TestNameHiding.B.j' hides inherited member 'TestNameHiding.A.j'. Use the new keyword if hiding was intended.

So to remove the warning message, we'll add new keyword ahead of the fields or methods in the derived class in order to hide the members with the same name in the base class.

Example 01-55-02

This example is changed from 01-55-01.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
using System;

namespace TestNameHiding
{
    public class A
    {
        public int i = 1;
        public int j = 2;

        public void test()
        {
            Console.WriteLine("A class");
        }
    }

    public class B : A
    {
        new public int j = 3;     // Add new here

        new public void test()    // Add new here
        {
            Console.WriteLine("B class");
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            A a = new A();
            Console.WriteLine("i={0}, j={1}", a.i, a.j);    // Output i=1, j=2
            a.test();                                       // Output A class
            B b = new B();
            Console.WriteLine("i={0}, j={1}", b.i, b.j);    // Output i=1, j=3
            b.test();                                       // Output B class
            Console.Read();
        }
    }
}

We only added new in line 18 and 20 to let the compiler know these members are redefined to hide the counterparts in the base class. After the change, the warning message will not be shown up.