In this article we are going to discuss Compile-Time Polymorphism in C#. There are many blogs, articles are available on the internet regarding Compile-Time Polymorphism but in this particular article I will try to explain to you with as much as simplest and realistic examples so you can get a clear idea of the Compile-Time Polymorphism use in C#.
Compile-Time Polymorphism (Static Polymorphism)
Compile-time polymorphism is achieved through method overloading and operator overloading. This type of polymorphism is resolved during compilation.
This type of polymorphism is resolved during compilation. Compile-time polymorphism is achieved through:
1. Method Overloading
Method overloading allows multiple methods in the same class to have the same name but different parameters (either in type or number and order of parameters).
Some Important points related to Method Overloading:
As you can see in the above image, all the methods are having the same name i.e. Method but with different parameters. If you look at the first two methods the number of parameters is different. The first method takes zero parameters while the second method takes one parameter. Then if you compare the second method with the third method, both are taking the same number of parameters but of different types. The second method takes an integer parameter while the Third method takes a string parameter. Further, if you compare the fourth and fifth method, both are having the same number of parameter but the order of the parameters are different. The fourth method takes the first parameter as an integer and the second parameter as a string while the Fifth method takes the first parameter as a string and the second parameter as an integer. So, every method is different in terms of number, type, and order of parameters, and this is called method overloading in C#.
Example
using System;
namespace MethodOverloading
{
public class Methodoveloading
{
public void Method()
{
Console.WriteLine("1st Method");
}
public void Method(int a)
{
Console.WriteLine("2nd Method");
}
public void Method(string b)
{
Console.WriteLine("3rd Method");
}
public void Method(int a, string b)
{
Console.WriteLine("4th Method");
}
public void Method(string b, int a)
{
Console.WriteLine("5th Method");
}
}
class Program
{
static void Main(string[] args)
{
Methodoveloading obj = new Methodoveloading();
obj.Method(); //Invoke the 1st Method
obj.Method(20); //Invoke the 2nd Method
obj.Method("Rohatash"); //Invoke the 3rd Method
obj.Method(20, "Rohatash"); //Invoke the 4th Method
obj.Method("Rohatash", 20); //Invoke the 5th Method
Console.ReadKey();
}
}
}
Output
Real World Example of Method overloading
To understand polymorphism, let's consider a bike that can be started in two different ways: through a kick start and a key start. Both methods serve the same purpose of starting the bike, but they involve different parameters.
public class Bike
{
// Method to start the bike using a key
public void Start(string keyType)
{
Console.WriteLine($"Bike started using {keyType} key.");
}
// Method to start the bike using a kick
public void Start(int kickForce)
{
Console.WriteLine($"Bike started with a kick of force {kickForce}.");
}
}
Why Return Type is not considered as part of Method Overloading in C#?
Here, I have written two methods with the same name but one method’s return type is void, and the other method’s return type is a int. See, as soon as we create the second method, the compiler itself gives the compile time error saying Type ‘Program’ already defines a member called ‘Method’ with the same parameter types.
Still, you have doubts, the return types are different. See, the return types come into the picture at the end of the method execution. But here, the confusion is not at the end of the method execution, but the confusion is about where to start, and which method to invoke.
2. Operator overloading
In C#, it is possible to make operators (such as +, -, *, ==, etc.) work with user-defined data types like classes or structs. That means C# has the ability to provide the operators with a special meaning for a data type, this ability is known as operator overloading.
It allowing objects to be manipulated using operators in a way that is natural for their type.
For example, we can overload the + operator in a class like String so that we can concatenate two strings by just using +. Using operator overloading in C# we can specify more than one meaning for an operator in one scope. The purpose of operator overloading is to provide a special meaning of an operator for a user-defined data type.
The following table describes the overloading ability of the various operators available in C#.
Operators | Description |
---|---|
+, -, !, ~, ++, – – | unary operators take one operand and can be overloaded. |
+, -, *, /, % | Binary operators take two operands and can be overloaded. |
==, !=, = | Comparison operators can be overloaded. |
&&, || | Conditional logical operators cannot be overloaded directly |
+=, -+, *=, /=, %=, = | Assignment operators cannot be overloaded. |
Key Points of Operator Overloading
Syntax
The general syntax for overloading an operator in C# is:
public static returnType operator operatorSymbol(parameters)
{
// method body
}
Example
In C#, the Operator functions are the same as normal functions. The only difference is, that the name of an operator function is always the operator keyword followed by the symbol of the operator, and operator functions are called when the corresponding operator is used.
Let’s consider a simple Complex number class and overload the + operator.
public class Complex
{
public double Real { get; set; }
public double Imaginary { get; set; }
public Complex(double real, double imaginary)
{
Real = real;
Imaginary = imaginary;
}
// Overloading the + operator
public static Complex operator +(Complex c1, Complex c2)
{
return new Complex(c1.Real + c2.Real, c1.Imaginary + c2.Imaginary);
}
public void Display()
{
Console.WriteLine($"{Real} + i{Imaginary}");
}
}
class Program
{
static void Main(string[] args)
{
Complex c1 = new Complex(1.0, 2.0);
Complex c2 = new Complex(3.0, 4.0);
Complex c3 = c1 + c2;
Console.WriteLine(c3);
c3.Display(); // Output: 4 + 6i
Console.ReadKey();
}
}
Output
Code Explanation