Override and New confusion in CSharp
Tags: csharp, override, new, oop
Published: 2022-12-31 10:14:55

Try to read this answer from SO first https://stackoverflow.com/a/11046733/15225066
If you understand that. no need to read this article.



I will not provide the formal definitions and shit. If you want that go to MSDN. 
## Overview
1. Some Basics 
2. Some Basics about "new" modifier
3. Example 1
5. Example 2 (do it yourself)

# Some Basics
Objects can have different blueprint at runtime when using inheritance.
First thing You need to understand is that There is difference between object reference and the actual object.

```csharp
	class Animal{/// Some code}
    class Cow : Animal{///Some code}
    
    static void Main()
    {
        Cow c = new Cow();
        // Note that we can also assign the Cow object to a Animal refrence
        Animal an = new Cow();
    }
```
(( Note that this `new` keyword is different. ))
`new Cow()` creates a object in heap returns its refrence(pointer or address of object in heap)
and we assign that to `c` variable which is refrence to a object of type of `Cow`.
`Cow c, Animal an` = Object reference
`new Cow()` = Actual Object

### Main Point
The runtime blueprint(Methods and member vars) belongs to a "Actual Object" not to refrence. whereas the Access to Blueprint is determined by the Object reference. (read this line again this is very important)
meaning the Methods and member vars that the object has, gets decided when the object is created. and to access those methods we need the refrence which limits the access to those methods.

```csharp
	class Animal
    {
        public virtual void Walk() { }
    }
    class Cow : Animal
    {
        public override void Walk() { }
        public void Milk() { }
    }

    static void Main()
    {
        Cow c = new Cow();

        // Note that I can also assign the Cow object to a Animal refrence
        Animal an = new Cow();
    }

```


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wkojcl9d67y38qiep15q.png)
* Object
	 * `new Cow()` 
	 * `new Cow()` 
	 * both are same
* methods in Object `new Cow()`
	* `void Cow.Milk()` 
	* `void Cow.Walk()`
* methods accesible with refrence `Animal an = new Cow()`
	* `void Cow.Walk()` (which is the overriden method)
* methods accesible with refrence `Cow c = new Cow()`
	* `void Cow.Walk()` (which is the overriden method)
	* `void Cow.Milk()` 

(1. Actual Object)
As you can see both `an` and `c` has same type of methods.

(2. Object Refrence)
only the refrence that you use to access Cow() object limits the access to methods.
With `c` you can access `void Cow.Milk()` and `void Cow.Walk()` 
but with `an` you can access `void Cow.Walk()` only.(which is the overriden method)

(1. Actual Object )
In this example above, when we create the object `new Cow()`, the methods it has are `Cow.Milk()` and `virtual void Animal.Walk()` but this Walk method is overriden by `override void Cow.Walk()` thus it has only to methods `Cow.Milk()` and `Cow.Walk()`. essentially when using `override` it replaces the `virtual` method.
(2. Object Refrence)
now based on what refrence you use for this object `new Cow()` that will determine what methods you can access. if you use `Animal an` reference then you can only use `Cow.Walk()` because the Animal refrence only has access to `Animal.Walk` Method which was replaced by `Cow.Walk()`. Thus `an.Walk()` will resolve to `Cow.Walk()`. where as `Cow.Milk()` exists on object but can not be called by `Animal an` refrence.



In general, the child reference has access to all the parent methods.

If you still didn't get the point you can experiment it yourself with inheritance and to examine the runtime behaviour you can use System.Refection ( I find it helpful to use in VS debugger Watch window as you can see in above Screengrab).

## Some Basics about "new" modifier
`new` modifier creates the new method with same signature as inherited method. it has no connection no inheritance.
consider `new` methods as methods which only allow the class in which it was declared to have access.
Look at the following code similar to the above case.
```csharp
	class Animal
    {
        public virtual void Walk() { }     //virtual here is optional
    }
    class Cow : Animal
    {
        public new void Walk() { }             // new here is also optional
        public void Milk() { }
    }

    static void Main()
    {
        Cow c = new Cow();

        // Note that I can also assign the Cow object to a Animal refrence
        Animal an = new Cow();

		c.Walk();       // calls Cow.Walk()
		an.Walk();      // calls Animal.Walk()
    }

```


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zbmocdbszu7vfme5lql7.png)
* Object
	 * `new Cow()` 
	 * `new Cow()` 
	 * both are same
* methods in Object `new Cow()`
	* `void Cow.Milk()` 
	* `void Cow.Walk()`
	* `void Animal.Walk()`
* methods accesible with refrence `Animal an = new Cow()`
	* `void Animal.Walk()` 
* methods accesible with refrence `Cow c = new Cow()`
	* `void Cow.Walk()` (which is the new method)
	* `void Cow.Milk()` 

(1. Actual Object)
similar to previous case both `new Cow()` objects contain same methods. 
But in this case we have two `Walk()` methods in the object. (and one `Milk()` method)
One of them is `Animal.Walk()` and other is `Cow.Walk()` .
So when we used `new` instead of `override` it did not replace the base class method instead it created a new method with the same signature in the derived class.

Now that we know what all methods the object contain. we can determine the access rules by using refrence types.

(2. Object Reference)
The Object `new Cow()` contains two similar methods `Animal.Walk()` ,`Cow.Walk()`.
when we call `an.Walk()` because the `Animal an` refrence has no access to any methods that its derived classes contains (general rule of inheritance). `an.Walk()` resolves to `Animal.Walk()`. 
When we call `c.Walk()` it resolves to `Cow.Walk()`. because the `Cow c` refrence has access to all methods of `Animal` and `Cow` (meaning access to all to three methods.). because we used `new` on `Cow.Walk()` it shadows the `Animal.Walk()` And thus call to `c.Walk()` resolves to `Cow.Walk()`.


## Example 1
```csharp
using System;
using System.Reflection;

public class NewVsOverride
{
    public class Base
    {
        public virtual void Method1()
        {
            Console.WriteLine("Base - Method1");
        }

        public virtual void Method2()
        {
            Console.WriteLine("Base - Method2");
        }
    }

    public class Derived:Base
    {
        public override void Method1()
        {
            Console.WriteLine("Derived - Method1");
        }

        public new void Method2()
        {
            Console.WriteLine("Derived - Method2");
        }
    }

    public static void test()
    {
        Base bc = new Base();
        bc.Method1();  
        bc.Method2();

        Derived dc = new Derived();
        dc.Method1();
        dc.Method2();

        Base bcdc = new Derived();
        bcdc.Method1();
        bcdc.Method2();
    }
}
```

* Object and Methods they contain.
 Base() | Derived() | Derived() 
 ------------ | --- | --- 
 `Base.Method1()`   | (overriden)`Derived.Method1()`| (overriden)`Derived.Method1()`
`Base.Method2()`   | (Shadowed in Derived) `Base.Method2()`| (Shadowed in Derived) `Base.Method2()`
 -- |  (new) `Derived.Method2()`  |  (new) `Derived.Method2()`
* Refrences and Methods they can access
 bc | dc | bcdc 
 ------------ | --- | --- 
 `bc.Method1()` -> Base.Method1()   | `dc.Method1()` -> (overriden)Derived.Method1()| `bcdc.Method1()` -> (overriden)Derived.Method1()
 `bc.Method2()` -> Base.Method2()   | (Shadowed) Base.Method2()  ( not accesible with Derived refrence)| `bcdc.Method2()` -> Base.Method2() (Shadowed in derived class not in base class.)
 -- | `dc.Method2() `-> (new) Derived.Method2()  |  (new) Derived.Method2()  (Base ref has no access to child)

## Example 2 (do it yourself)
Similarly try to understand the following example.
when calling test() from main.

```csharp
using System;
using System.Reflection;
public class NewVsOverride2
{
    public class Base
    {
        public virtual void Method1()
        {
            Console.WriteLine("Base - Method1");
            Method2();  // will call Base.Method2 because Base.Method1 has no access to Shadowed new Derived.Method2
        }

        public virtual void Method2()
        {
            Console.WriteLine("Base - Method2");
        }
    }

    public class Derived : Base
    {
        //comment Derived.Method1 for test2
        public override void Method1()
        {
            Console.WriteLine("Derived - Method1");
            Method2(); //will call Derived.Method2 because In Derived Method2 is shadowed 
        }

        public new void Method2()
        {
            Console.WriteLine("Derived - Method2");
        }
    }

    public class Derived2 : Derived
    {
        public override void Method1()
        {
            Console.WriteLine("Derived2 - Method1");
        }

        public new void Method2()
        {
            Console.WriteLine("Derived2 - Method2");
        }
    }

    public static void test()
    {
        test0();
        
        Console.WriteLine();
        test1();
        Console.WriteLine();
        
        test2();
        
    }

    public static void test0()
    {
        Base bc = new Base();
        bc.Method1();
        bc.Method2();

        Derived dc = new Derived();
        dc.Method1();
        dc.Method2();

        Base bcdc = new Derived();
        bcdc.Method1();
        bcdc.Method2();

        Derived2 d2 = new Derived2();
        d2.Method1();
        d2.Method2();
    }

    public static void test1()
    {
        Derived dc = new Derived();
        dc.Method1();
        Base bcdc = dc;
        bcdc.Method1();
        dc.Method2();
    }

    //comment Derived.Method1 for test2
    public static void test2()
    {
        Derived dc = new Derived();
        dc.Method1();
        Base bcdc = dc;
        bcdc.Method1();
        dc.Method2();
    }
}
```
Note:  for test2 comment Derived.Method1
Output:
```
//test0
Base - Method1
Base - Method2
Base - Method2
Derived - Method1
Derived - Method2
Derived - Method2
Derived - Method1
Derived - Method2
Base - Method2
Derived2 - Method1
Derived2 - Method2
```
```
//test1
Derived - Method1
Derived - Method2
Derived - Method1
Derived - Method2
Derived - Method2
```
```
//test2
Base - Method1
Base - Method2
Base - Method1
Base - Method2
Derived - Method2
```
if you understood outputs for `test1()` and `test2()` . I think that will be it.

Refrences:
https://stackoverflow.com/a/11046733/15225066
https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/knowing-when-to-use-override-and-new-keywords
https://stackoverflow.com/questions/17717570/why-does-calling-a-method-in-my-derived-class-call-the-base-class-method
https://stackoverflow.com/questions/11046387/exact-difference-between-overriding-and-hiding