Difference between shadowing and overriding in C#?

后端 未结 6 924
面向向阳花
面向向阳花 2020-11-22 07:25

What\'s difference between shadowing and overriding a method in C#?

6条回答
  •  南方客
    南方客 (楼主)
    2020-11-22 07:51

    Shadowing is actually VB parlance for what we would refer to as hiding in C#.

    Often hiding (shadowing in VB) and overriding are shown as in answer by Stormenet.

    A virtual method is shown to be overridden by a sub-class and calls to that method even on the super-class type or from inside code of the super-class will call the replacement implementation from the sub-class.

    Then a concrete method is shown (one not marked as virtual or abstract) being hidden by using the new keyword when defining a method with an identical signature on the sub-class. In this case when the method is called on the super-class type the original implementation is used, the new implementation is only available on the sub-class.

    However what is often missed is that it is also possible to hide a virtual method.

    class A
    {
        public virtual void DoStuff() { // original implementation }
    }
    
    class B : A
    {
        public new void DoStuff() {  //new implementation }
    }
    
    B b = new B();
    A a = b;
    
    b.DoStuff(); //calls new implementation
    a.DoStuff(); //calls original implementation.
    

    Note in the above example DoStuff becomes concrete and can not be overriden. However it is also possible to use both the virtual and new keywords together.

    class A
    {
        public virtual void DoStuff() { // original implementation }
    }
    
    class B : A
    {
        public new virtual void DoStuff() {  //new implementation }
    }
    
    class C : B
    {
        public override void DoStuff() { //replacement implementation }
    }
    
    C c = new C();
    B b = c;
    A a = b;
    
    c.DoStuff(); //calls replacement implementation
    b.DoStuff(); //calls replacement implementation
    a.DoStuff(); //calls original implementation.
    

    Note that despite all the methods involved being virtual, the override on C does not affect the virtual method on A because of the use of new in B hides the A implementation.

    Edit: Its been noted in the comments to this answer that the above may be dangerous or at least not particularly useful. I would say yes it can be dangerous and would be out there if it were at all useful.

    In particular you could get into all sorts of trouble if you also change the accessability modifiers. For example:-

    public class Foo
    {
        internal Foo() { }
        protected virtual string Thing() { return "foo"; }
    }
    
    public class Bar : Foo
    {
     internal new string Thing() { return "bar"; }
    }
    

    To an external inheritor of Bar, Foo's implementation of Thing() remains accesible and overridable. All legal and explainable according to .NET type rules neverless quite unintuative.

    I've posted this answer to deepen an understanding of how things work not as a suggestion of techniques that can be used freely.

提交回复
热议问题