Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> C#

Deconstructors ใน C# 7.0 คืออะไร

C# อนุญาตให้ใช้ Multiple Deconstructor Methods ในโปรแกรมเดียวกัน ด้วยจำนวน Out Parameters เท่ากัน หรือ จำนวนและ Type ของ Out Parameters เท่ากันแต่ลำดับต่างกัน

มันเป็นส่วนหนึ่งของ Tuple Syntax ใหม่ - ไม่เกี่ยวกับ Tuple Classes แต่มาจาก Functional Programming

Keyword Deconstruct ใช้สำหรับ Deconstructors

ตัวอย่างพื้นฐาน


public class Employee {
    public Employee(string employeeName, string firstName, string lastName) {
        EmployeeName = employeeName;
        FirstName = firstName;
        LastName = lastName;
    }
    
    public string EmployeeName { get; }
    public string FirstName { get; }
    public string LastName { get; }
    
    // Deconstructor
    public void Deconstruct(out string employeeName, out string firstName, out string lastName) {
        employeeName = EmployeeName;
        firstName = FirstName;
        lastName = LastName;
    }
}

class Program {
    public static void Main() {
        Employee employee = new Employee("emp", "fname", "lname");
        
        // Deconstruction Assignment
        (string eName, string fName, string lName) = employee;
        
        Console.WriteLine(eName);  // emp
        Console.WriteLine(fName);  // fname
        Console.WriteLine(lName);  // lname
        Console.ReadLine();
    }
}

Output


emp
fname
lname

Multiple Deconstructors (Overloading)


public class Point {
    public int X { get; }
    public int Y { get; }
    public int Z { get; }
    
    public Point(int x, int y, int z = 0) {
        X = x; Y = y; Z = z;
    }
    
    // Deconstruct 2D
    public void Deconstruct(out int x, out int y) {
        x = X; y = Y;
    }
    
    // Deconstruct 3D
    public void Deconstruct(out int x, out int y, out int z) {
        x = X; y = Y; z = Z;
    }
}

// Usage
var p1 = new Point(1, 2);
var (x1, y1) = p1;        // ใช้ Deconstruct 2D

var p2 = new Point(1, 2, 3);
var (x2, y2, z2) = p2;    // ใช้ Deconstruct 3D

Deconstruction กับ Tuples


// Tuple Deconstruction (Built-in)
(string first, string last) = ("John", "Doe");
var (city, country) = ("Bangkok", "Thailand");

// Discard (_) สำหรับค่าที่ไม่ต้องการ
var (name, _, age) = GetPerson(); // Ignore middle value

Deconstruction ใน Foreach (C# 7.0+)


var people = new[] {
    new Person("John", 25),
    new Person("Jane", 30)
};

foreach (var (name, age) in people) {
    Console.WriteLine($"{name} is {age} years old");
}

// กับ Dictionary
var dict = new Dictionary { ["a"] = 1, ["b"] = 2 };
foreach (var (key, value) in dict) {
    Console.WriteLine($"{key} = {value}");
}

Extension Deconstructors (สำหรับ Types ที่แก้ไม่ได้)


// สำหรับ System.Drawing.Point (Sealed, ไม่มี Deconstruct)
public static class PointExtensions {
    public static void Deconstruct(this Point p, out int x, out int y) {
        x = p.X; y = p.Y;
    }
}

// Usage
Point p = new Point(10, 20);
var (x, y) = p;  // ใช้ Extension Deconstruct

Positional Records (C# 9.0+) - Auto Deconstruct


// Record Auto-generates Deconstructor
public record Person(string FirstName, string LastName, int Age);

// Usage
var person = new Person("John", "Doe", 30);
var (first, last, age) = person;  // Auto Deconstruct
// หรือ
var (first, last, _) = person;    // Discard Age

เมื่อไหร่ควร Implement Deconstruct

  • Value-like Types (Data Containers, DTOs, Records)
  • Types ที่มี Fields/Properties จำนวนน้อย (2-5)
  • เมื่อ Client Code จะ Destructuring บ่อย
  • Tuple-like Semantics

ข้อควรระวัง

  • Deconstructor ต้องเป็น Instance Method (ไม่ใช่ Static)
  • Parameters ต้องเป็น out ทั้งหมด
  • ชื่อ Method ต้องเป็น Deconstruct อย่างแน่นอน
  • Multiple Deconstructors ต้องมี Signature ต่างกัน (จำนวน/Type Parameters)
  • ไม่ใช่ Destructor (~ClassName()) - นั่เป็น Finalizer