3

So the past two days I've been on several interviews for dev positions and two of the companies asked very similar question. For the most part I think I understand what and why is going on, there are some things that I don't know why they work the way they work, and finally besides the explanation I would like if someone can direct me to those parts of C# which a responsible for this behavior since I would like to read about this topic more in depth.

First, the question from the interview:

class Program
{


    static void Main(string[] args)
    {
        A a = new B();
        Console.WriteLine("A a = new B() => a.PrintName Result");
        a.PrintName(); //Output "BBB" as expected
        Console.WriteLine("----------------");
        A c = new C();
        Console.WriteLine("A c = new C() => c.PrintName Result");
        c.PrintName(); //Otuput is again "BBB". What about shadowing?
    }

}

public class A
{
    public virtual void PrintName()
    {
        Console.WriteLine("AAA");
    }
}

public class B : A
{
    public override void PrintName()
    {
        Console.WriteLine("BBB");
    }
}

public class C : B
{
    public new void PrintName()
    {
        Console.WriteLine("CCC");
    }
}

The questions are regarding the code in the Main method where as you can see variable a is declared with type A but then is instantiated with new B(), the similar thing is happening here A c = new C(); but as you can see in class C instead overriding the PrintName method, it's declared using the new keyword, which from my (obviously incomplete understanding) should still provide the implementation in class C when the variable is instantiated with this type, however as you can see in the comments after the method invocation the result is BBB for both cases. So my first question is what logic lies behind this behavior. And also as a side question since during the time of the interview I wasn't sure about the right answer I tried to apply some logic which was fairly simple and stated that according the (If I'm not mistaken) MSDN recommendation it's better to use var keyword instead of concrete types and actually if we don't explicitly specify the type of the variable like so:

 var c = new C();
 Console.WriteLine("A c = new C() => c.PrintName Result");
 c.PrintName(); //Otuput is "CCC"

sure enough we get CCC. This second question is provoked more of a curiosity, since obviously using var and concrete type are not always interchangeable and as we can see we can get completely different result based on that. I'm not using this as some sort of excuse or stuff like that. If you write code it's expected to know what your code is doing, so maybe this recommendations implicitly assume that the developer is aware of those this and can make his choice accordingly or, after all this is more of a trick to see in candidate knows his stuff and at the end of the day using var is always preferable and this sort of coding is not encouraged (I wish it was so) or there are valid case where we want to take advantage from this exact behavior that I described?

Leron
  • 9,546
  • 35
  • 156
  • 257
  • Just out of curiosity, where the comments inplace when you got the code? Or did he ask you what the output will be and what the reasons are why its so? – Rand Random Aug 04 '17 at 16:58
  • 1
    Shadowing is the reason it *doesn't* provide `CCC` - `B` overrides `A`, `C` doesn't override `B` further. – Ant P Aug 04 '17 at 16:58
  • @RandRandom The comments are added by my. I thought this will make it more easier to clarify my question in terms of what I get and my thought on what I expect to get. – Leron Aug 04 '17 at 17:01
  • If you're interestied in the internal workings of C#, I recommend that you read "More effective C#" by Bill Wanger. It's a great book. – Dido Aug 04 '17 at 17:01
  • The behavior you see is because the PrintName() method is virtual, and therefore dynamically bound. You use the "new" modifier to redefine non-virtual members inherited from a base class. Non-virtual methods are statically bound. Any source code that calls C.PrintName() (I know it's not a static method) calls exactly it. With virtual methods, the runtime invokes the proper function based on the runtime type of the object. The "new" modifier makes behavior dependent on the reference you use to invoke the method. I use it only when a library I use introduces a new method that causes a conflict. – Dido Aug 04 '17 at 17:15
  • *"(...)using the new keyword, which from my (obviously incomplete understanding) should still provide the implementation in class C (...)"*. Well if that were the case there would be no use in having both `new` and `override` in the language. You've just spotted an obvious difference between the two. – InBetween Aug 04 '17 at 17:17
  • @InBetween the original answer actually is pretty good. Thanks for the reference. – Leron Aug 04 '17 at 17:39

0 Answers0