Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> C#

Gọi Constructor từ Constructor khác trong cùng Class C#: Từ khóa this

Hai từ khóa Constructor Chaining

Từ khóaGọi constructorCú pháp
thisConstructor khác cùng class: this(args)
baseConstructor base class (parent): base(args)

Constructor Chaining với this()

Cho phép tái sử dụng logic khởi tạo, tránh duplicate code.


public class Demo 
{
    public string Name { get; set; }
    public int Age { get; set; }
    public string Address { get; set; }
    
    // 1. Constructor đầy đủ nhất (chứa logic chính)
    public Demo(string name, int age, string address) 
    {
        Console.WriteLine("Full constructor called");
        Name = name;
        Age = age;
        Address = address;
    }
    
    // 2. Gọi constructor 3 tham số
    public Demo(string name, int age) : this(name, age, "Unknown") 
    {
        Console.WriteLine("2-param constructor called");
    }
    
    // 3. Gọi constructor 2 tham số
    public Demo(string name) : this(name, 0) 
    {
        Console.WriteLine("1-param constructor called");
    }
    
    // 4. Parameterless → gọi 1 tham số
    public Demo() : this("Anonymous") 
    {
        Console.WriteLine("Parameterless constructor called");
    }
}

class Program 
{
    static void Main() 
    {
        Console.WriteLine("=== new Demo() ===");
        var d1 = new Demo();
        
        Console.WriteLine("\n=== new Demo('John') ===");
        var d2 = new Demo("John");
        
        Console.WriteLine("\n=== new Demo('Jane', 25) ===");
        var d3 = new Demo("Jane", 25);
        
        Console.WriteLine("\n=== new Demo('Bob', 30, 'NYC') ===");
        var d4 = new Demo("Bob", 30, "NYC");
        
        Console.ReadLine();
    }
}

Kết quả chạy

=== new Demo() ===
Full constructor called
1-param constructor called
Parameterless constructor called

=== new Demo('John') ===
Full constructor called
2-param constructor called
1-param constructor called

=== new Demo('Jane', 25) ===
Full constructor called
2-param constructor called

=== new Demo('Bob', 30, 'NYC') ===
Full constructor called

Quy tắc Constructor Chaining

  1. this() hoặc base() phải là statement đầu tiên trong constructor body.
  2. Không thể dùng cả this() và base() cùng lúc.
  3. Có thể chain nhiều cấp: A() : this(1) { } → this(int) : this(1,2) { } → this(int,int) { }
  4. Tránh circular chaining (A→B→A) → StackOverflow.

Kết hợp this() và base()


public class Base 
{
    public Base(int x) { Console.WriteLine($"Base({x})"); }
    public Base(int x, int y) { Console.WriteLine($"Base({x},{y})"); }
}

public class Derived : Base 
{
    // Gọi base(int)
    public Derived(int a) : base(a) { }
    
    // Gọi base(int,int)
    public Derived(int a, int b) : base(a, b) { }
    
    // Gọi Derived(int,int) → base(int,int)
    public Derived(int a, int b, int c) : this(a, b) { }
}

Best Practices

  • Constructor "Master": Có nhiều tham số nhất, chứa logic khởi tạo chính.
  • Các constructor khác delegate về master qua this() với default values.
  • Validation, complex init logic → đặt ở master constructor.
  • Cân nhắc Factory Methods thay vì nhiều constructor phức tạp.

// Factory Method Pattern - thay thế nhiều constructor
public class User 
{
    public string Name { get; private set; }
    public string Email { get; private set; }
    public int Age { get; private set; }
    
    private User(string name, string email, int age) 
    {
        Name = name; Email = email; Age = age;
    }
    
    public static User CreateAdult(string name, string email, int age) 
    {
        if (age < 18) throw new ArgumentException("Must be 18+");
        return new User(name, email, age);
    }
    
    public static User CreateMinor(string name, string email, int age, string guardian) 
    {
        if (age >= 18) throw new ArgumentException("Must be under 18");
        return new User(name, email, age);
    }
}

C# 12: Primary Constructors (Class/Struct)


// C# 12 - Primary constructor parameters tự động thành field
public class Service(string name, int timeout = 30, bool retry = true) 
{
    // name, timeout, retry có sẵn như field private
    public void Run() => Console.WriteLine($"{name}: {timeout}s, retry={retry}");
    
    // Constructor phụ vẫn dùng this()
    public Service(string name) : this(name, 30, true) { }
}

var s = new Service("API", 60, false);