Constructor Chaining คืออะไร?
การเรียก Constructor อีกตัวหนึ่งใน Class เดียวกัน เพื่อ Reuse Code ลด Duplication
- ใช้ Keyword:
this() - ต้องอยู่ใน Constructor Initializer (หลัง Parameter List ก่อน Body)
Syntax
public MyClass(int a, int b) : this(a) // เรียก Constructor ที่รับ 1 Parameter
{
// Body
}
ตัวอย่าง: Chaining หลายระดับ
using System;
class Demo
{
// 1. Parameter-less
public Demo()
{
Console.WriteLine("Parameter-less constructor called");
}
// 2. 2 Parameters - เรียก Parameter-less
public Demo(int first, int second) : this()
{
Console.WriteLine($"{first} {second}");
}
// 3. 3 Parameters - เรียก 2 Parameters
public Demo(int first, int second, int third) : this(first, second)
{
Console.WriteLine($"{first} {second} {third}");
}
}
class Program
{
static void Main()
{
Console.WriteLine("=== Create with 3 params ===");
Demo obj = new Demo(1, 2, 3);
Console.WriteLine("\n=== Create with 2 params ===");
Demo obj2 = new Demo(10, 20);
Console.WriteLine("\n=== Create with 0 params ===");
Demo obj3 = new Demo();
Console.ReadLine();
}
}
Output
=== Create with 3 params === Parameter-less constructor called 1 2 1 2 3 === Create with 2 params === Parameter-less constructor called 10 20 === Create with 0 params === Parameter-less constructor called
เรียก Base Constructor (Parent Class)
ใช้ base() แทน this()
class BaseClass
{
public BaseClass(int a, int b, int c)
{
Console.WriteLine($"Base: {a} {b} {c}");
}
}
class Derived : BaseClass
{
public Derived(int a, int b, int c) : base(a, b, c)
{
Console.WriteLine($"Derived: {a} {b} {c}");
}
}
Output
Base: 1 2 3 Derived: 1 2 3
Execution Order (ลำดับการทำงาน)
- Base Constructor (ทั้ง Chain จนถึง Parameter-less)
- this() Chain (ใน Derived Class)
- Derived Constructor Body
class A { public A() { Console.WriteLine("A"); } }
class B : A { public B() : this(1) { Console.WriteLine("B()"); } public B(int x) { Console.WriteLine("B(int)"); } }
// new B() Output:
// A
// B(int)
// B()
Best Practices
- ✅ ให้ Constructor ที่มี Parameter มากที่สุดเป็น "Master" (ทำงานจริง)
- ✅ Constructor น้อย Parameter เรียก Master ด้วย Default Values
- ✅ ใช้
this()ลด Code Duplication - ❌ ไม่ทำ Circular Chaining (A→B→A) → StackOverflow
- ❌ ไม่ใช้
this()และbase()ร่วมใน Constructor เดียวกัน
C# 11+ Required Members (Alternative)
// แทน Constructor Overloading ใช้ Required Properties
public class Person
{
public required string Name { get; init; }
public required int Age { get; init; }
public string Email { get; init; } = ""; // Optional
}
// ใช้งาน - Compiler บังคับให้ Set Required Properties
var p = new Person { Name = "John", Age = 30 };