Virtual Keyword in C#

We have seen Class, Inheritance, etc. in our previous article. In this article let us discuss the virtual keyword in c#. This is one of the common interview topics in C#.

Virtual Keyword or Modifier in C#

When we declare a method, property, indexer, or event declaration, etc with a virtual keyword, we are informing the derived class that this method can be overridden. This means a derived class can have a customized implementation for a virtual method (or others).   We cannot use a virtual modifier with static, abstract private, or override modifiers. This can be very useful when a derived class has different logic or improved logic for some features, then overriding comes to the rescue.

virtual keyword in c# with example
Virtual Keyword in C# with Example

To override a virtual method in a derived class, we need to add an override keyword for the method which we are trying to override.

Points to Remember when using Virtual Keyword

  • Virtual Methods needs to be marked with “Virtual” Keyword in the base class.
  • Derived Class will override the virtual method by using the “Override” keyword.
  • It is not possible to mark an abstract member as virtual.
  • When Virtual Method called, execution checks for the overridden members if found it will be called.
  • A virtual keyword cannot be used with Private & Static members.
  • It is not mandatory to override a method marked as virtual.

Use of Virtual Keyword in C#

  • Derived Class can have custom implementation for the required members without modifying parent implementation.
  • .NET Framework has ToString() , Equals(), etc. as virtual, It helps to customize these functions based on the requirement.

Below is a sample example of a virtual method overridden in the derived class.

using System;
namespace Learn
{
    public class Parent
    {
        public virtual void Print()
        {
            Console.WriteLine("Printing from Base Class");
        }
        public virtual void Publish()
        {
            Console.WriteLine("Publishing from Base Class");
        }
    }
    public class Derived:Parent
    {
        public override void Print()
        {
            Console.WriteLine("Printing from Derived Class");
        }
    }
    class Learn
    {
        public static void Main(string[] args)
        {
            Derived d = new Derived();
            d.Print();//Printing from Derived Class
            d.Publish();//Publishing from Base Class

        }
    }
}

In the above example, two methods Print() & Publish() in Parent class marked as virtual methods. The class Derived overrides Print() method to have a different implementation.

When we invoke the Print() method on the instance of the derived class, it refers to the overridden method. Whereas for Publish() we haven’t overridden so it points to base class implementation. So we have the flexibility to override certain methods based on our requirements.

Overridden Methods on Reference Variables.

In the previous example, we have created an instance of a derived class with a reference variable that is also derived type. The below example explains which method will be called based on the type of reference variable pointing to the instance.

Parent p2 = new Derived("Ram");

if the derived instance is pointed to the base class reference variable, when the method is called then the derived class overridden method will be invoked.

using System;
namespace Learn
{
    public class Parent
    {
        //Marking this method virtual makes it 
        //overridable by a Derived Class 
        public virtual void Greet()
        {
            Console.WriteLine("Hi Good Morning");
        }
    }
    public class Derived : Parent
    {
        private string _Name;
        public Derived(string Name)
        {
            this._Name = Name;
        }
        //Overrding base class implementation 
        public override void Greet()
        {
            Console.WriteLine("Hi Good Morning {0}", _Name);
        }
    }
    class Practice
    {
        public static void Main(string[] args)
        {
            Parent p1 = new Parent();
            p1.Greet();
            //Hi Good Morning 
            Derived d1 = new Derived("John");
            d1.Greet();
            //Hi Good Morning John 
            Parent p2 = new Derived("Ram");
            p2.Greet();
            //Hi Good Morning Ram 
        }
    }
}

Shadowing or Method hiding in C#

 In C# When we have a scenario where base class and child class methods (or property or index) Share a common name compiler will issue a warning. In that case, we can use a new keyword to tell the compiler to hide the base class implementation which means the new method is independent of the base class method.

Below example explains this concept.

using System;
namespace Learn
{
    public class Parent
    {
        //Marking this method virtual makes it 
        //overridable by a Derived Class 
        public virtual void Greet()
        {
            Console.WriteLine("Hi Good Morning");
        }
    }
    public class Derived : Parent
    {
        private string _Name;
        public Derived(string Name)
        {
            this._Name = Name;
        } //using new keyword to confirm 
          //hiding base class implementation is inteded
        public new void Greet()
        {
            Console.WriteLine("Hi Good Morning {0}", _Name);
        }
    }
    class Practice
    {
        public static void Main(string[] args)
        {
            Parent p1 = new Parent();
            p1.Greet();
            //Hi Good Morning 
            Derived d1 = new Derived("John");
            d1.Greet();
            //Hi Good Morning John 
            Parent p2 = new Derived("Ram");
            p2.Greet();
            //Hi Good Morning 
        }
    }
}
virtual override and new keyword in c#

Overriding ToString & Equals

Class in C# derived from System.Object type also the ToString() & the Equals method is virtual.So We can override these methods in any class. Sometimes it is very helpful to have a custom implementation for ToString() where we can customize the output as we want. Similarly, we can override equals methods so that comparison for equality becomes easier.

In the below example we have overridden these methods. The Student is a sample class with 4 properties. In order to display all these properties in the console window, we have overridden the ToString() method. Similarly Equals method also overridden.

using System;
namespace Learn
{
    public class Student
    {
        private string _name;
        private int _id;
        private int _age;
        private int _marks;

        public Student(string Name, int Id, int Age, int Marks)
        {
            this._name = Name;
            this._age = Age;
            this._marks = Marks;
            this._id = Id;
        }

        public override string ToString()
        {
            return $"Name={_name},Id={_id},Age={_age},Marks={_marks}";
        }

        public override bool Equals(object obj)
        {
            if ((obj == null) || !this.GetType().Equals(obj.GetType()))
            {
                return false;
            }

            Student s = obj as Student;

            if (s._age == this._age && s._name == this._name && s._marks == this._marks && s._id == this._id)
                return true;
            return false;
        }

        public override int GetHashCode()
        {
            return this._id;
        }
    }
    class Learn
    {
        public static void Main(string[] args)
        {
            Student student1 = new Student("John", 12345, 16, 90);
            Console.WriteLine(student1);

            Student student2 = new Student("John", 12345, 16, 90);
            Console.WriteLine(student2);

            Student student3 = new Student("Catherine", 12344, 16, 90);
            Console.WriteLine(student3);

            //Compare Student1 and Student2
            Console.WriteLine(student1.Equals(student2));
            //Compare Student1 and Student3
            Console.WriteLine(student1.Equals(student3));


        }
    }
}

Leave a Reply