-1

I have multilevel inheritance of 3 classes

class Product1
{
    public virtual void Show()
    {
        Console.WriteLine("Product1.show");
    }
}
class Product2 : Product1
{
    public override void Show()
    {
        Console.WriteLine("Product2.show");
    }
}
class Product3 : Product2
{
    public new void Show()
    {
        Console.WriteLine("Product3.show");
    }
}

At the time of object creation, I'm assigning object of Product3 to Product1.

class Products
    {
        static void Main()
        {
            Product1 product1 = new Product1();
            Product3 product3 = new Product3();

            product1 = product3;

            product3.Show();
            product1.Show();
        }
    }

And called Show method. I thought in both the cases the answer would be Product3.show but not sure how Product2.show is being called.

Console screenshot

Any help on the explanation would be appreciated :)

  • Note that instead of a screenshot, just "Output: " and then the output would be clearer. – Jon Skeet Mar 18 '21 at 12:30
  • If you already know the difference between `new` and `override` (because you use both), maybe you are confused that the `Prduct3.Show` is not called even if you assign an instance of `Prduct3`. The reason is that you assign it to a vaiable of type `Product1` and not `Product3`. – Tim Schmelter Mar 18 '21 at 12:38
  • @TimSchmelter, I's expecting `Product3` twice! As I've assigned object of `Product3` to `Product1`. But as you clarified that it's not possible?! I'm still confused, why in the world `Product2`.Show came in the picture – kardinal Mar 18 '21 at 12:42
  • @kardinal: What is expecting `Product3` twice and what is not possible? Sorry but your comment confuses me. Of course it's possible to get _"Show Product3"_ twice. You just need to replace the `new` keyword with `override`. The keyword `new` creates a new method which has nothing to do with the inherited method `Show`(just the name). – Tim Schmelter Mar 18 '21 at 12:44
  • @TimSchmelter, I was expecting `Product3` twice as I assigned `Product3` to `Product1`. But as you said this assignment is not possible because 'Product1' is of different type. And I still don't know why `Product2` came into the picture – kardinal Mar 18 '21 at 12:47
  • @kardinal: Of course the assignment is possible and in fact it works. You just dont get the expected output `"Product3.show"` if you assign the `Product3` to a `"Product1` variable. Therefore you have to assin it to a `Product3` variable or (normally the correct way) `override` the method instead of using `new`. – Tim Schmelter Mar 18 '21 at 12:48
  • @TimSchmelter, ok! but why `product1.Show()` prints Product2.show after `product1 = product3` ? :( – kardinal Mar 18 '21 at 12:51
  • 1
    @kardinal: because you override `Show` in `Product2` and actually this is a `Product3` instance that inherits from `Product2`. Inheritance works even if you "hide" an instance in a parent type(class or interface). – Tim Schmelter Mar 18 '21 at 12:57

1 Answers1

1

Your Product3.Show method is effectively an entirely different method as far as the compiler is concerned from Product1.Show which is overridden by Product2.Show. By using the new modifier you've explicitly isolated it from the existing Show method. The C# compiler (and CLR) are working exactly as I'd expect them to.

Basically if you want Product3.Show to be called even via a reference with a compile-time type of Product1 or Product2, you should use override instead of new.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • I'm still confused, why in the world `Product2.Show` came into the picture. :( – kardinal Mar 18 '21 at 12:44
  • @kardinal: because you use `new` instead of `override` in `Product3`. Period. You assign that `Product3` to a `Product1` variable, so the compiler loses the information that this `Product1` has a new implementation of `Show`(defined in `Product3)` and uses the normal inheritance to `Product2`. You would have to cast it to `Product3` before you call `Show` to be able to see the `"Product3.show"`. – Tim Schmelter Mar 18 '21 at 12:51
  • @TimSchmelter, could you please elaborate how in this case `new` is working? It should have only worked for `Product3`, where it used. Why it is working for `Product1` ? Just because of this - `product1 = product3` – kardinal Mar 18 '21 at 12:56
  • @TimSchmelter, I did not read your edited version. Make sense now. Thanks Man – kardinal Mar 18 '21 at 13:02