We can't talk about virtual members without referring to polymorphism. In fact, a function, property, indexer or event in a base class marked as virtual will allow override from a derived class.
By default, members of a class are non-virtual and cannot be marked as that if static, abstract, private, or override modifiers.
Example Let's consider the ToString() method in System.Object. Because this method is a member of System.Object it's inherited in all classes and will provide the ToString() methods to all of them.
namespace VirtualMembersArticle
{
public class Company
{
public string Name { get; set; }
}
class Program
{
static void Main(string[] args)
{
Company company = new Company() { Name = "Microsoft" };
Console.WriteLine($"{company.ToString()}");
Console.ReadLine();
}
}
}
The output of the previous code is:
VirtualMembersArticle.Company
Let's consider that we want to change the standard behavior of the ToString() methods inherited from System.Object in our Company class. To achieve this goal it's enough to use the override keyword to declare another implementation of that method.
public class Company
{
...
public override string ToString()
{
return $"Name: {this.Name}";
}
}
Now, when a virtual method is invoked, the run-time will check for an overriding member in its derived class and will call it if present. The output of our application will then be:
Name: Microsoft
In fact, if you check the System.Object class you will find that the method is marked as virtual.
namespace System
{
[NullableContextAttribute(2)]
public class Object
{
....
public virtual string? ToString();
....
}
}