Click here to Skip to main content
15,308,835 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
See more:
I saw the following piece of code, what is the result, and why?
I understand it 80% but not fully. Thanks.

C#
using System;
public class Program
    {
        public static  void Main()
        {
            classA a = new classC();
            Console.WriteLine(a.Print());
        }
 
        public class classA
        {
            public virtual string Print()
            {
                return "classA";
            }
        }
 
        public class classB : classA
        {
            public override string Print()
            {
                return "classB";
            }
        }
 
        public class classC : classB
        {
            public new string Print()
            {
                return "ClassC";
            }
        }
    }


What I have tried:

see above code for details, just run it.
Posted
Updated 15-Jan-21 11:45am
v2
Comments
PIEBALDconsult 15-Jan-21 17:02pm
   
"I understand it 80% but not fully" -- then you understand 0%.
Member 14707431 15-Jan-21 17:11pm
   
:), you are right.

1 solution

a is a variable that can hold an instance of classA - which includes any class which is derived from it.
So since ClassC is derived from ClassB, which in turn derives from ClassA when you create an instance of ClassC, you can assign it to a - but that doesn't change the instance, it just means you can only call ClassA methods on it.

When you call Print, the system looks for the highest method with a matching signature in the inheritance chain - which is the ClassB version which overrides the ClassA version because ClassC doesn't override Print from ClassB, it creates a new method of the same signature that "hides" the previous versions.

If you do this instead:
public static  void Main()
    {
    classC c = new classC();
    classA a = c;
    Console.WriteLine(a.Print());
    Console.WriteLine(c.Print());
    }
You will get the ClassB and ClassC methods called because the first is looking for the ClassA version (overridden by ClassB)and the second is specifically looking for the ClassC method.
   
Comments
Member 14707431 16-Jan-21 2:53am
   
Hi, OriginalGriff, thank you very much!
based your comments, my understanding is as follows, can you please check whether my understanding is fully correct? I appreciate it very much.
with classA a = new classC(), menaing a can only call ClassA methods. But due to the virtual keyword with Print() within ClassA, therefore, a can not call Print() itself within ClassA, instead it looks for the version which overrides it, and this is Print() within ClassB. Once Print() has been overridden by ClassB, then ClassC (derived from ClassB) can not override it anymore (even without new, nothing will be changed). If no virtual in ClassA, then the output of this code will be "ClassA".
OriginalGriff 16-Jan-21 4:36am
   
No, read what I said again.
Member 14707431 16-Jan-21 12:14pm
   
Hi, to be clear, I just tested one case, if the override keyword is removed for the Print() from ClassB, then classA a = new classC(), then a.Print() output is ClassA, simply because the Print() in ClassA is not overridden by any class, right?
OriginalGriff 16-Jan-21 12:21pm
   
Yes, but ... you'll also get a compiler Warning: "'Program.classB.Print()' hides inherited member 'Program.classA.Print()'

And as a beginner, you should very certainly have "Treat warnings as errors" set to TRUE because at the moment, the compiler very much does know better than you do! :laugh:

As it happens, my default projects are all modified to enable that option, because I make mistakes, and it does know better than I do sometimes as well!
Member 14707431 16-Jan-21 13:24pm
   
your are right, sometimes, warnings are better treated as errors. but sometimes, warnings are different from errors, the most important thing is to understand the logic behind them. thanks for the clarification.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900