Polymorphism (พอลิโมร์ฟิซึม) ใน C# แบ่งเป็น 2 ประเภทหลัก ตามเวลาที่ตัดสินใจว่าเมธอดไหนจะถูกเรียก (Method Resolution)
1. Static Binding (Compile-time Polymorphism / Early Binding)
การเชื่อมโยงเมธอดกับออบเจ็กต์เกิดขึ้น **ระหว่างคอมไพล์ (Compile Time)** คอมไพเลอร์ทราบล่วงหน้าว่าเมธอดไหนจะถูกเรียก
รูปแบบหลัก 2 แบบ:
Function Overloading (Method Overloading)
public class Calculator {
// Overload ต่างกันที่ จำนวนพารามิเตอร์
public int Add(int a, int b) => a + b;
public int Add(int a, int b, int c) => a + b + c;
// Overload ต่างกันที่ ชนิดพารามิเตอร์
public double Add(double a, double b) => a + b;
public string Add(string a, string b) => a + b;
}
Operator Overloading
public class Vector {
public int X, Y;
public Vector(int x, int y) { X = x; Y = y; }
// Overload + operator
public static Vector operator +(Vector a, Vector b) {
return new Vector(a.X + b.X, a.Y + b.Y);
}
// Overload == และ != (ต้องคู่กัน)
public static bool operator ==(Vector a, Vector b) {
return a.X == b.X && a.Y == b.Y;
}
public static bool operator !=(Vector a, Vector b) {
return !(a == b);
}
}
Operator Overloading Rules
| กลุ่ม | Operators | สามารถ Overload ได้? |
|---|---|---|
| Unary | + - ! ~ ++ -- true false |
✅ ได้ |
| Binary Arithmetic | + - * / % |
✅ ได้ |
| Comparison | == != < > <= >= |
✅ ได้ (ต้องคู่กัน) |
| Logical | && || |
❌ ไม่ได้โดยตรง (แต่ได้ผ่าน true/false + & |) |
| Assignment | += -= *= /= %= |
❌ ไม่ได้ (Compound assignment ใช้ operator พื้นฐาน) |
| Others | = . ?: ?? new is sizeof typeof |
❌ ไม่ได้ |
2. Dynamic Binding (Runtime Polymorphism / Late Binding)
การตัดสินใจว่าเมธอดไหนจะถูกเรียก เกิดขึ้น **ระหว่างรันไทม์ (Runtime)** โดยอาศัย Mechanism ของ **Method Overriding**
Abstract Classes
public abstract class Shape {
public abstract double Area(); // Abstract method - ไม่มี Body
public void PrintInfo() { // Concrete method - มี Body
Console.WriteLine("This is a shape");
}
}
public class Circle : Shape {
public double Radius { get; set; }
public override double Area() { // Override abstract method
return Math.PI * Radius * Radius;
}
}
public class Rectangle : Shape {
public double Width { get; set; }
public double Height { get; set; }
public override double Area() {
return Width * Height;
}
}
// ใช้งาน - Dynamic Dispatch
Shape s1 = new Circle { Radius = 5 };
Shape s2 = new Rectangle { Width = 4, Height = 6 };
Console.WriteLine(s1.Area()); // 78.54 - เรียก Circle.Area() รันไทม์
Console.WriteLine(s2.Area()); // 24 - เรียก Rectangle.Area() รันไทม์
Virtual Methods
public class Animal {
public virtual void Speak() { // Virtual - สามารถ Override ได้
Console.WriteLine("Animal sound");
}
}
public class Dog : Animal {
public override void Speak() { // Override
Console.WriteLine("Woof!");
}
}
public class Cat : Animal {
public override void Speak() {
Console.WriteLine("Meow~");
}
}
// Runtime Polymorphism
Animal a1 = new Dog();
Animal a2 = new Cat();
a1.Speak(); // Woof! - 決定在運行時
a2.Speak(); // Meow~
Static vs Dynamic Binding - สรุปเปรียบเทียบ
| ด้าน | Static Binding | Dynamic Binding |
|---|---|---|
| ชื่ออื่น | Early Binding, Compile-time Polymorphism | Late Binding, Runtime Polymorphism |
| กลไก | Method Overloading, Operator Overloading | Method Overriding (virtual/abstract) |
| เวลาตัดสินใจ | Compile Time | Runtime |
| Performance | เร็วกว่า (Direct call) | ช้ากว่าเล็กน้อย (vtable lookup) |
| Flexibility | น้อยกว่า | สูง (Extensible) |
| ใช้เมื่อ | Logic คงที่, Utility Methods | ต้องการ Extensibility, Plugin Architecture |
Dynamic Keyword (C# 4.0+) - Dynamic Binding แบบ Explicit
dynamic d = "Hello";
Console.WriteLine(d.Length); // 5 - Resolved at runtime
d = 123;
Console.WriteLine(d.Length); // RuntimeBinderException: 'int' ไม่มี Length
// ใช้กับ Anonymous Types, COM, JSON, Dynamic Languages
dynamic obj = new { Name = "John", Age = 30 };
Console.WriteLine(obj.Name); // John