Back to Basics: C# Polymorphism

Alex Maher
6 min readMay 22, 2023

--

Polymorphism — a concept that may seem daunting to many new programmers. What exactly is polymorphism? If you’re familiar with Greek, you might know that “poly” means many and “morph” means forms. So, in the simplest terms, polymorphism allows an object to take on many forms.

It’s funny how our journey through life often circles back to the beginning, isn’t it? The same can be said for our understanding and mastery of any subject. The more we learn, the more we realize the significance of the fundamental principles that underpin everything else. Today, I find myself reflecting on the basics of C# programming, specifically on one of the most fundamental yet powerful concepts in object-oriented programming: polymorphism.

Basics of Object-Oriented Programming

In the world of programming, especially in C#, polymorphism is a fundamental concept of Object-Oriented Programming (OOP). Let’s understand this step-by-step.

Classes and Objects in C#

We all know real-world objects like cars, dogs, or people, right? In OOP, these real-world objects are translated into ‘classes’ which define the properties (or ‘attributes’) and behaviors (or ‘methods’) that an object can have. The real instances of these classes are known as ‘objects’.

In C#, a class is a blueprint for an object, and an object is an instance of a class. Let’s break this down with some examples.

Defining a Class in C#

Here’s an example of a simple class named Car:

public class Car
{
// Properties of the Car class
public string Make { get; set; }
public string Model { get; set; }
public string Color { get; set; }

// Method of the Car class
public void Drive()
{
Console.WriteLine("The car is driving.");
}
}

In this example, Car is a class that has three properties (Make, Model, and Color) and one method (Drive).

Creating an Object in C#

An object is an instance of a class. To create an object of the Car class, you can do the following:

Car myCar = new Car();

In this example, myCar is an object of the Car class.

Inheritance in C#

Inheritance is a fundamental principle in object-oriented programming. It allows you to create new classes that reuse, extend, and modify behavior defined in other classes. The class whose members are inherited is called the base class, and the class that inherits those members is called the derived class.

Base Class in C#

Let’s start by defining a base class Animal. This class has properties like Name and Age, and a method Eat:

public class Animal
{
public string Name { get; set; }
public int Age { get; set; }

public void Eat()
{
Console.WriteLine($"{Name} is eating.");
}
}

Derived Class in C#

Now, we can create a derived class Dog that inherits from the Animal class and has an additional method Bark:

public class Dog : Animal
{
public void Bark()
{
Console.WriteLine($"{Name} is barking.");
}
}

The : operator is used to inherit the Dog class from the Animal class.

Using Inheritance in C#

You can now create an object of the Dog class and access both the methods from the base Animal class and the derived Dog class:

Dog myDog = new Dog();
myDog.Name = "Buddy";
myDog.Age = 5;
myDog.Eat();
myDog.Bark();

This will output:

Buddy is eating.
Buddy is barking.

In this example, myDog is an object of the Dog class. Even though we didn't define the Eat method or the Name property in the Dog class, we can use them because the Dog class inherits from the Animal class.

Polymorphism in C#

In C#, Polymorphism is divided into two types: static and dynamic. Both of these have their unique characteristics and uses.

Static Polymorphism

Method Overloading in C#

Static polymorphism, also known as compile-time polymorphism, involves method overloading. This is where multiple methods have the same name but different parameters.

Method overloading involves creating multiple methods with the same name but different parameters:

public class Calculator
{
public int Add(int a, int b)
{
return a + b;
}

public int Add(int a, int b, int c)
{
return a + b + c;
}
}

In this example, the Calculator class has two methods named Add. One adds two integers, and the other adds three integers.

Dynamic Polymorphism

Method Overriding in C#

Dynamic polymorphism, or run-time polymorphism, involves method overriding. This is where a method in a derived class has the same name and parameters as a method in its base class.

Method overriding involves a base class method being overridden in a derived class:

public class Animal
{
public virtual void MakeSound()
{
Console.WriteLine("The animal makes a sound");
}
}

public class Dog : Animal
{
public override void MakeSound()
{
Console.WriteLine("The dog barks");
}
}

In this example, the Animal class has a method MakeSound that is marked as virtual, which means it can be overridden in a derived class. The Dog class is derived from Animal and overrides the MakeSound method.

To see the polymorphism in action, you can do:

Animal myAnimal = new Animal();
Animal myDog = new Dog();
myAnimal.MakeSound(); // Outputs: "The animal makes a sound"
myDog.MakeSound(); // Outputs: "The dog barks"

In this example, myAnimal and myDog are both objects of type Animal. However, myDog is actually an instance of the Dog class. This is why it uses the MakeSound method defined in Dog rather than the one in Animal.

Benefits of Polymorphism in C#

Polymorphism is an integral part of OOP in C# for many reasons. It increases code reusability, enhances program structure, and boosts code readability and maintainability.

Common Mistakes with Polymorphism in C#

Like any programming concept, it’s easy to make mistakes with polymorphism if you’re not careful. From forgetting to declare virtual methods to improperly using base classes, the pitfalls are endless. But don’t worry, with practice comes perfection.

1. Don’t override a method without the virtual keyword in the base class. If a method in the base class is not marked as virtual, attempting to override it in a derived class will result in a compile-time error.

public class Animal
{
public void MakeSound()
{
Console.WriteLine("The animal makes a sound");
}
}

public class Dog : Animal
{
public override void MakeSound() // This will cause a compile-time error
{
Console.WriteLine("The dog barks");
}
}

2. Remember to override keyword when intending to override a method. If you're trying to override a method but forget to include the override keyword, C# will treat it as a new method, and polymorphism won't work as intended.

public class Animal
{
public virtual void MakeSound()
{
Console.WriteLine("The animal makes a sound");
}
}

public class Dog : Animal
{
public void MakeSound() // Should be marked as 'override' to correctly override the base method
{
Console.WriteLine("The dog barks");
}
}

3. Don’t attempt to override a sealed method. If a method in the base class is marked as sealed, it cannot be overridden in a derived class. Trying to do so will result in a compile-time error.

public class Animal
{
public virtual void MakeSound()
{
Console.WriteLine("The animal makes a sound");
}
}

public sealed class Dog : Animal
{
public override void MakeSound() // This will cause a compile-time error as Dog class is sealed
{
Console.WriteLine("The dog barks");
}
}

4. Remember to call the base class’ method in the derived class if needed. If you override a method and still want to include the functionality of the base class’ method, you should call it using base.MethodName(). If you forget to do this, the base method's functionality won't be included

public class Animal
{
public virtual void Eat()
{
Console.WriteLine("The animal is eating");
}
}

public class Dog : Animal
{
public override void Eat()
{
// The base.Eat() is missing here, so "The animal is eating" won't be printed
Console.WriteLine("The dog is eating a bone");
}
}

Polymorphism is one of the core pillars of OOP and an essential skill in C#. Through understanding and applying this concept, you can write more efficient, clean, and flexible code.

FAQs about C# Polymorphism

  1. What is the main difference between static and dynamic polymorphism? Static polymorphism is determined at compile-time, whereas dynamic polymorphism is determined at run-time.
  2. How is polymorphism used in real-world programming? Polymorphism is used in scenarios like user interface design, database handling, or game development, to name a few.
  3. What are the benefits of using polymorphism in C#? Polymorphism increases code reusability, enhances program structure, and boosts code readability and maintainability.
  4. What are some common mistakes made with polymorphism? Common mistakes include forgetting to declare virtual methods and improperly using base classes.

Thank you for reading!

🔗 If you liked the article, connect with me by subscribing!

🚀 Give me a clap and follow for more articles!

🌟 FacebookStay updated with my latest content!

--

--

Alex Maher

.NET C# dev with 10+ yrs exp, self-taught & passionate web developer. Sharing tips & experiences in C# and web dev.