locked
Method Overriding in C#

    Question


  • i have few question from the below code

    code as follows

    class BC
    {
      public void Display()
      {
         System.Console.WriteLine("BC::Display");
      }
    }

    class DC : BC
    {
      new public void Display()
      {
         System.Console.WriteLine("DC::Display");
      }
    }

    class Demo
    {
      public static void Main()
      {
         BC b;
         b = new BC();
         b.Display();    

         b = new DC();
         b.Display();    
      }
    }

    BC b;
    b = new BC();
    b.Display();  

    from the above code we can understand the base class Display() method will be called.

    b = new DC();
    b.Display();

    but from the above code it is clear that derived class Display() is hiding through using new keyword and that why base class Display() will be called.

    actually i want to know what new keyword is doing internally.
    it was mention from where i got the code that

    Since b contains a reference to object of type DC one would expect the function Display() of class DC to get executed. But that does not happen. Instead what is executed is the Display() of BC class. That's because the function is invoked based on type of the reference and not to what the reference variable b refers to. Since b is a reference of type BC, the function Display() of class BC will be invoked, no matter whom b refers to. Take one more example.

    one line is not clear to me that ---- "because the function is invoked based on type of the reference and not to what the reference variable b refers to"

    what does it mean that function is invoked based on type of the reference here

    b = new DC();
    b.Display();  

    what is the type of b here. it the beginning b was declared as instance name of class BC but later b become the instance of class dc.

    i am very confused about the line called "because the function is invoked based on type of the reference and not to what the reference variable b refers to"

    please discuss in detail. thanks
    Saturday, July 16, 2011 5:54 PM

All replies



  • one line is not clear to me that ---- "because the function is invoked based on type of the reference and not to what the reference variable b refers to"


    Hi,

    since your Reference is a Reference to BC (in the declaration: BC b;) the type of the Reference is BC and not DC even you assign a new DC to the variable b.

    b = new DC(); b.Display(); what is the type of b here. it the beginning b was declared as instance name of class BC but later b become the instance of class dc.

    The type of b is DC Check with:

     

      Console.WriteLine(b.GetType().ToString());
    
    but the Type of the Reference is still BC.

     

    See the difference in overriding the method:

     

     class Program
     {
     static void Main(string[] args)
     {
     BC b;
     b = new BC();
     b.Display();
    
     b = new DC();
    
     b.Display();
     Console.ReadKey();
     }
    
     class BC
     {
     public virtual void Display()
     {
     System.Console.WriteLine("BC::Display");
     }
     }
    
     class DC : BC
     {
     public override void Display()
     {
     System.Console.WriteLine("DC::Display");
     }
     }
     }
    

    The output now is BC... and DC...

     

    Regards,

      Thorsten





    Saturday, July 16, 2011 7:04 PM
  • It  is strongly recommended that you do you use "new" for overriding a non-virtual method.  The reason is that it doesn't work the way you think it does - as demonstrated by your code.  The fact that you expected one thing but got another is a clear indication as to why it should never be used. 

    The problem is that virtual methods are bound at runtime.  That means that at runtime the CLR (or equivalent thereof) determines which version to called based upon the exact type of the object in question.  This has a performance hit but is pretty standard for OO languages.  However since it is a runtime behavior the language that was originally used is pretty much irrelevant.

    For non-virtual methods the compiler knows at compilation time exactly which version to call (the only one that is in scope).  If there were more than one possible candidate then the code wouldn't compile.  Hence at compile time the compiler generates a direct call to the method (sort of like the CLR would do at runtime once it determines the proper type).  Since you can't override it there is no benefit to deferring until runtime. 

    Now suppose the compiler sees obj.Foo.  The compiler looks to see if it is virtual by scanning the members of obj's type (including base types).  If Foo is found to be virtual then the compiler inserts a "stub" that will detemine the method to call at runtime.  If Foo is not virtual then a direct method call is inserted by the compiler.  So given obj.Foo where obj is of type BC and Foo is not virtual the compiler will insert a call to BC.Foo irrelevant of the actual type of obj.  Note that "new" has no impact on this behavior.  A non-virtual or a "new" method both generate direct calls to the method at compile time.

    So why do we have "new"?  Because without it a DC wouldn't compile if it attempted to override a base, non-virtual method.  Beyond that it really doesn't have any impact on generated code.  At compile time if the compiler sees obj.Foo and obj is declared (not defined) as BC then it uses BC.Foo.  If obj is declared as DC then it uses DC.Foo instead (assuming DC "newed" Foo).  Note that the actual instantiated type (the new T() call) isn't relevant here).  The compiler uses the type of obj as it was declared for determination of what method to call.

    In summary, the reason it is recommended that you not use "new" is because it only works IF you declare the instance as the type that "newed" the method.  Otherwise it will defer to the base type's implementation anyway.  Debugging this behavior can be tricky as it doesn't work the way most people would read it as working.

    Michael Taylor - 7/16/2011
    http://msmvps.com/blogs/p3net

     

    Saturday, July 16, 2011 7:22 PM
    Moderator
  • Overriding a method is done by a modifier keyword "override". The condition is that that the mathod in the base class is marked as "virtual" or even "abstract".

    The way you did, using a "new" keyoword, you can override the mathod in base class too, but the main difference is that you cann never access to the method in base class. Becuase when using "new" this is then the base method.

    In the way that Thorsten shows an example you can easily access to the base method as well, you only use a "base" keyword:

     class DC : BC
     {
        public override void Display()
        {
           base.Display(); //this will 1st execute the method in base class
           //then this one here in overriden class:
           System.Console.WriteLine("DC::Display");
        }   
     }
    


    As said, if using "new" keyword, you will not get permision to access to the method in base class, even if this is a correct way too (one of the correct ways).

    Hope it helps,


    Mitja
    Saturday, July 16, 2011 7:23 PM
  • Hi Mou_kolkata;

    To this statement:

    b = new DC();
    b.Display();

    but from the above code it is clear that derived class Display() is hiding through using new keyword and that why base class Display() will be called.

     Although it is true that the use of the new keywork on the Display method in class DC in this case it is not the reason why BC.Display was called. The b was defined to be of type BC earlier in the code and it is the only type it can hold. Seeming that DC derives from BC the system did an implied cast of DC to BC and because it has morphed to type BC it only knows about the functions and property of type BC and NOT DC.

     To this question :

    actually i want to know what new keyword is doing internally.

     You can hide members without the use of the new keyword modifier, the result is a warning. If you use new to explicitly hide a member, it suppresses this warning and documents the fact that the derived version is intended as a replacement.  "new Modifier (C# Reference)"

    To your question :

    one line is not clear to me that ---- "because the function is invoked based on type of the reference and not to what the reference variable b refers to"
     
    what does it mean that function is invoked based on type of the reference here
     
    b = new DC();
    b.Display();

     This is what is called "Polymorphism in object-oriented programming" see the link.

    To your question : 

    what is the type of b here. In the beginning b was declared as instance name of class BC but later b become the instance of class dc.

    Because b can only hold an instance of BC and because DC derives from BC, b only see the properties and methods of a type BC even though in memory it has all the properties of DC as well but only has access to the properties of BC type.

     


    Fernando (MCSD)

    If a post answers your question, please click "Mark As Answer" on that post and "Mark as Helpful".
    Saturday, July 16, 2011 7:23 PM
  • In method overriding what kind of message is sent to compiler with new keyword.  

    class DC : BC
    {
      new public void Display()
      {
         System.Console.WriteLine("DC::Display");
      }
    }

    Tuesday, July 19, 2011 7:58 AM
  • In method overriding what kind of message is sent to compiler with new keyword.  

    class DC : BC
    {
      new public void Display()
      {
         System.Console.WriteLine("DC::Display");
      }
    }

    Tuesday, July 19, 2011 7:58 AM
  • In method overriding what kind of message is sent to compiler with new keyword.  

    class DC : BC
    {
      new public void Display()
      {
         System.Console.WriteLine("DC::Display");
      }
    }

    Tuesday, July 19, 2011 7:59 AM
  • In simple words, new is always meant to create a new instance. So when you are using new before the draw method, it is creating a new instance of Display thus overriding the inherited one.

    You can take it as, Functions are actually abstract variables that can load from and store at accumulator.

    Friday, August 12, 2011 11:22 PM
  • New is not always meant to create a new instance. To quote the help:

    In C#, the new keyword can be used as an operator, a modifier, or a constraint.

    new Operator

    Used to create objects and invoke constructors.

    new Modifier

    Used to hide an inherited member from a base class member.

    new Constraint

    Used to restrict types that might be used as arguments for a type parameter in a generic declaration

    When used as a modifier to a method it does not create instances of the method - it hides the method in the base class.



    Regards David R
    ---------------------------------------------------------------
    Every program eventually becomes rococo, and then rubble. - Alan Perlis
    The only valid measurement of code quality: WTFs/minute.
    Saturday, August 13, 2011 5:29 PM