C# Exception Handling
C# File I/O
C# Delegates and Events
C# Generics
C# Async Programming
C# Polymorphism

C# Polymorphism

Polymorphism means "many shapes" — the same method call behaves differently depending on the actual type of the object.

1 - Runtime Polymorphism (virtual/override)

public class Shape
{
    public virtual double Area() => 0;
    public override string ToString() => $"{GetType().Name}: area={Area():F2}";
}

public class Rectangle : Shape
{
    public Rectangle(double w, double h) { Width = w; Height = h; }
    public double Width  { get; }
    public double Height { get; }
    public override double Area() => Width * Height;
}

public class Circle : Shape
{
    public Circle(double r) => Radius = r;
    public double Radius { get; }
    public override double Area() => Math.PI * Radius * Radius;
}

Shape[] shapes = { new Rectangle(5, 3), new Circle(4) };
foreach (var s in shapes)
    Console.WriteLine(s); // calls the correct Area()
// Rectangle: area=15.00
// Circle: area=50.27

2 - is and as Operators

Shape s = new Circle(3);

if (s is Circle c)
    Console.WriteLine($"Radius: {c.Radius}"); // pattern matching

var r = s as Rectangle;
Console.WriteLine(r is null ? "Not a Rectangle" : r.Width.ToString());

3 - new Keyword (Hiding)

public class Base   { public string Name => "Base"; }
public class Child  : Base { public new string Name => "Child"; }

Base obj = new Child();
Console.WriteLine(obj.Name); // "Base" — hiding, not overriding!

Note: Prefer override over new for method replacement. The new keyword hides the base member rather than overriding it, which can cause confusing behaviour when the object is accessed through a base-class reference.

-Tip-