Fields và Properties trong C# và thay đổi trong C# 14

March 3, 2025 0 By Nam Vu

Chẳng là mấy ngày qua Microsoft mới ra mắt .Net 10 Preview và C# 14. Cũng có khá nhiều điểm hay ho bạn có thể đọc chi tiết tại trang chủ nhé!

Nhân tiện có một điểm nói về Fields trong version mới và chắc nhiều anh em mới có thể ít khi để ý phân biệt Fields vs Properties. Bài viết này cùng mình xem lại 2 từ khóa này có gì khác nhau nhé!

Trong lập trình hướng đối tượng (OOP) với C#, field là một biến cấp class hoặc struct dùng để lưu trữ dữ liệu cụ thể của một instance (đối tượng). Nó tạo nên danh tính (identity) của một instance và được gọi là instance fields.

Theo nguyên tắc thì bạn nên giữ các biến ở phạm vi private (thường sử dụng dấu gạch dưới làm tiền tố – clean code chỉ vậy) để ngăn truy cập bên ngoài và chỉ cung cấp quyền truy cập thông qua properties hoặc methods.

Vậy bạn có đặt khóa bảo vệ kho báu của mình không? Đó chính là cách hoạt động của biến private. Chúng được “ẩn” bên trong một lớp và thường được đặt tiền tố bằng dấu gạch dưới để dễ nhận diện. Tuy nhiên, chúng ta không cần phải phá khóa để truy cập, vì đã có những “chìa khóa đặc biệt” – properties hoặc methods giúp kiểm soát việc truy cập dữ liệu này.

Ví dụ về cách khai báo fields trong một class:

public class Person {
    // Khai báo một field private để lưu tên
    private string _firstName;
    // Khai báo một field private khác để lưu chức danh
    private string _jobTitle;
}

Trong đoạn code trên, các field _firstName_jobTitle được giữ ở mức private. Điều này giúp kiểm soát hoàn toàn cách dữ liệu được truy cập hoặc sửa đổi, đảm bảo tính toàn vẹn và bảo mật dữ liệu.

Fields không chỉ tồn tại trong class mà còn có thể được tìm thấy trong:

  • Structs: Tương tự như các khối xây dựng trong trò chơi lắp ráp, mỗi thành phần phải được khởi tạo riêng lẻ khi tạo một instance mới.
  • Nested classes: Giống như những con búp bê gì gì của Nga lồng vào nhau, nested class là các lớp nằm bên trong một lớp khác. Các fields trong nested class chỉ có thể được truy cập bên trong class đó hoặc từ class cha.
  • Partial classes: Nếu bạn thích ghép hình, partial class sẽ rất thú vị. Bạn có thể khai báo các fields trong nhiều file khác nhau và sau đó hợp nhất chúng thành một class hoàn chỉnh.

Tầm quan trọng của Fields trong cấu trúc class

Fields trong code giống như các ngăn bí mật trong một cuốn nhật ký. Bạn có thể quyết định ai được phép truy cập vào chúng dựa trên các mức bảo vệ như private, protected, và public.

Ví dụ minh họa:

public class Codename {
    private string _firstName;
    private string _lastName;

    public Codename(string firstName, string lastName) {
        this._firstName = firstName;
        this._lastName = lastName;
    }

    public string GetFirstName() {
        return _firstName;
    }

    public void SetFirstName(string firstName) {
        this._firstName = firstName;
    }

    public string GetLastName() {
        return _lastName;
    }

    public void SetLastName(string lastName) {
        this._lastName = lastName;
    }

    public string RevealIdentity() {
        return $"{_firstName} {_lastName}";
    }
}

Fields giúp giữ danh tính của đối tượng bí mật, đồng thời cho phép truy cập thông qua các phương thức được kiểm soát.

Vậy Properties có vai trò gì?

Properties đóng vai trò là các phương thức đặc biệt cung cấp khả năng getter và setter cho fields. Khi properties được gọi, chúng hoạt động như những phương thức truy xuất dữ liệu, giúp tương tác với fields trở nên dễ dàng và linh hoạt hơn.

Ví dụ đơn giản về property:

public class Avatar {
    private string _handle;

    public string Handle {
        get {
            return _handle;
        }
        set {
            _handle = value;
        }
    }
}

Trong đoạn code trên, field _handle được truy cập thông qua property Handle. Nếu bạn muốn một cách viết đơn giản hơn, có thể sử dụng auto-implemented properties:

public class Avatar {
    public string Handle { get; set; }
}

Ở đây, compiler sẽ tự động tạo một field ẩn cho property Handle, giúp code gọn gàng hơn mà vẫn đảm bảo tính năng tương tự.

Hãy thử cải tiến class Identity của chúng ta bằng cách sử dụng properties:

public class Identity {
    private string _moniker;
    private string _designation;

    public Identity(string moniker, string designation) {
        this._moniker = moniker;
        this._designation = designation;
    }

    public string Moniker {
        get { return _moniker; }
        set { _moniker = value; }
    }

    public string Designation {
        get { return _designation; }
        set { _designation = value; }
    }

    public string ComputeFullName() {
        return $"{_designation} {_moniker}";
    }
}

Sau khi chuyển sang sử dụng properties, class Identity trở nên dễ đọc và dễ bảo trì hơn.

Lưu ý quan trọng

Một lỗi phổ biến khi làm việc với properties là sử dụng cùng một tên cho property và field, dẫn đến lỗi Stack Overflow do vòng lặp vô hạn.

Ví dụ lỗi:

public class Superhero {
    public string HeroName {
        get { return HeroName; } // Sai: Truy cập chính property thay vì field
        set { HeroName = value; } // Sai: Gán giá trị vào chính property
    }
}

static void Main(string[] args) {
    Superhero superman = new Superhero();
    superman.HeroName = "Superman"; // Gây lỗi vòng lặp vô hạn
}

Khi HeroName được gán giá trị, nó gọi setter của chính nó, tạo vòng lặp vô tận và làm tràn bộ nhớ hệ thống.

Quy tắc quan trọng:

  • Luôn sử dụng field bên trong getter và setter của property.
  • Đặt tên field khác với property để tránh nhầm lẫn.
  • Sử dụng auto-implemented properties khi không cần logic bổ sung.

Fields và Properties đóng vai trò quan trọng trong việc quản lý dữ liệu bên trong class. Fields giúp lưu trữ thông tin một cách an toàn, trong khi properties giúp kiểm soát truy cập vào dữ liệu một cách linh hoạt hơn.

Với C# 14, Field-backed properties giúp tối ưu hóa việc chuyển đổi giữa auto-implemented properties và properties có logic tùy chỉnh, giúp code trở nên sạch hơn và dễ bảo trì hơn.

https://github.com/dotnet/core/blob/main/release-notes/10.0/preview/preview1/csharp.md#field-backed-properties

Anh em có thể thực hành nhiều hơn để tránh lỗi và tối ưu hóa hiệu suất ứng dụng của anh em nhé!

#ntechdevelopers