Readonly – Writeonly Properties và Automatic Properties


Trong bài trước, chúng ta đã tìm hiểu sơ qua khái niệm về Properties trong C#, hôm nay chúng ta sẽ tiếp tục tìm hiểu về Property để có thể áp dụng được nó vào thực tế khi lập trình ứng dụng.

1. ReadOnly – WriteOnly Property

Nếu các bạn còn nhớ, trong phần trước chúng ta đã tạo ra một chương trình minh họa đơn giản với Property. Cụ thể, chúng ta đã tạo ra lớp Person có dạng như sau với phần thuộc tính name đã được bỏ đi nhằm đơn giản code.

class Person
{
    private int age;
    public int Age
    {
        set
        {
            if (value <= 0)
                age = 1;
            else
                age = value;
        }
        get
        {
            return age;
        }
    }
}

Chúng ta thấy rằng Property cung cấp cho chúng ta hai phần với hai từ khóa: get và set. Việc get là dùng để trả về dữ liệu cho bên ngoài, việc set là để thiết lập dữ liệu cho đối tượng. Tuy nhiên, có những trường hợp mà chúng ta muốn tạo một đối tượng chỉ cho phép lấy dữ liệu chứ không cho lớp bên ngoài thay đổi dữ liệu bên trong thì chúng ta sẽ sử dụng ReadOnly Property (Để dễ hình dung, bạn hãy nghĩ về những thông số trong đồng hồ đo km của xe máy, các thông số này sẽ chỉ thay đổi thông qua những hành động khác như đạp thắng, rồ ga chứ không thể thay đổi trực tiếp các số này được, nhưng người lái xe lại có thể thấy được trực tiếp là mình đã đi bao nhiêu km).
Để làm tạo ra ReadOnly Property, chúng ta đơn giản chỉ cần bỏ phần set ra khỏi khai báo property. Đối với ví dụ trước, chúng ta hãy tưởng tượng rằng đối tượng ngoài chỉ có thể lấy được thông tin về Tuổi của đối tượng chứ không thể nào thay đổi được giá trị tuổi đó. Việc thay đổi chỉ có thể thực hiện được từ những phương thức thuộc lớp đó.

class Person
{
    private int age;
    public int Age
    {
        get
        {
            return age;
        }
    }
    public void Smoke()
    {
        age++;
    }
}

Trong đoạn mã trên, chúng ta đã bỏ đi phần set của Property để nó trở thành ReadOnly, đồng thời bổ sung thêm một phương thức Smoke() sẽ làm cho age của đối tượng Person tăng thêm 1 đơn vị. Như thế, nếu giả sử một lớp nào khác tạo đối tượng Person thì họ chỉ có thể lấy được tuổi mà không thể thay đổi được nó (việc thay đổi phải thực hiện từ bên trong đối tượng nhờ phương thức Smoke):

Person p = new Person();
//Lỗi, Age là readonly Property
//p.Age = 10;
p.Smoke();
Console.WriteLine(p.Age);

Tương tự, WriteOnly Property là những property mà không có thành phần get. Mặc dù loại property này rất ít gặp trong thực tế nhưng chúng ta vẫn có thể tạo ra được property này trong một vài trường hợp cần đến. Một ví dụ là chúng ta có thể thay đổi password nhưng không thể lấy được giá trị của password (thông thường password được mã hóa 1 chiều, do đó chúng ta chỉ có lưu trữ và so sánh password). Trở lại với ví dụ Person ở trên, lần này chúng ta sẽ tạo Property age là WriteOnly (thử tưởng tượng về một người có khả năng muốn trẻ hoặc già tùy ý nhưng không ai biết chính xác tuổi của anh ta tại một thời điểm nào đó).

class Person
{
    private int age;
    public int Age
    {
        set
        {
            if (value <= 0)
                age = 1;
            else
                age = value;
        }
    }
}

Lúc này, bạn chắc chắn sẽ không thể nào in ra được giá trị của một đối tượng Person mặc dù bạn hoàn toàn có khả năng thay đổi được giá trị bên trong của nó, ví dụ

Person p = new Person();
p.Age = 10;
//Lỗi, Age là WriteOnly
//Console.WriteLine(p.Age);

2. Automatic Properties

Nhiều khi trong ứng dụng của chúng ta đang viết, chúng ta sẽ phải tạo ra những lớp chỉ dùng để mô tả cấu trúc dữ liệu mà nó sẽ chứa (hay gọi là các Entity). Ví dụ như khi phải tạo một danh sách sinh viên có các thông tin: Tên, Tuổi thì chúng ta sẽ phải tạo ra một lớp Student như sau:

class Student
{
    public string name;
    public string Name
    {
        get { return name; }
        set { name = value; }
    }
    public int age;
    public int Age
    {
        get { return age; }
        set { age = value; }
    }
}

Có thể bạn thắc mắc rằng tại sao lại phải sử dụng get, set để bảo vệ các trường dữ liệu nameage mà không hề có đoạn mã dùng để kiểm tra, chẳng phải là chỉ cần sử dụng các public field là nhanh hơn sao?. Ở đây, mục đích của chúng ta muốn rằng đoạn mã trên sẽ có khả năng mở rộng khi chúng ta muốn thêm vào việc kiểm tra logic hoặc là biến nó thành các thành phần ReadOnly hoặc WriteOnly mà không làm ảnh hưởng tới những thành phần khác trong chương trình.

Tuy nhiên, khi chúng ta chưa thêm việc kiểm tra logic vào mà phải viết giống như trên thì thật là bất tiện và dài dòng, nhưng C# 3.0 đã bổ sung cho chúng ta một tính năng mới giải quyết điều này: Automatic Properties.

Để khai báo Automatic Properties thì chúng ta sẽ bỏ các field đi và chỉ để lại các từ khóa get/set như trong ví dụ sau:

class Student
{
    public string Name { get; set; }
    public int Age { get; set; }
}

Khi sử dụng đoạn mã trên và biên dịch, trình biên dịch C# sẽ tự động thêm vào các private field vào cho đối tượng tương ứng với từng Property. Chúng ta hoàn toàn có thể tạo một đối tượng, thay đổi, lấy giá trị của các Properties:

Student s = new Student();
s.Name = "Jamesbond";
s.Age = 10;
Console.WriteLine(s.Age);

Với việc sử dụng Automatic Properties như thế này, việc mở rộng cho lớp Student này của chúng ta rất là uyển chuyển. Giả sử chương trình chúng ta yêu cầu rằng tuổi của sinh viên phải luôn luôn lớn hơn 15 thì chúng ta sẽ bổ sung thêm private field như sau:

class Student
{
    public string Name { get; set; }
    private int age;
    public int Age
    {
        get
        {
            return age;
        }
        set
        {
            if (value < 15)
                age = 15;
            else
                age = value;
        }
    }
}

Đối với những đoạn mã có sử dụng lớp này thì hoàn toàn không cần phải thay đổi gì cả vì chúng ta vẫn giữ nguyên tên của Properties mà chỉ bổ sung thêm các thành phần khác.

Kết luận: Properties được sử dụng rất nhiều trong khi lập trình ứng dụng với C#, tùy theo từng trường hợp mà chúng ta có thể sử dụng Readonly hay Writeonly Properties. Automatic Properties là một tính năng hay được sử dụng nhằm mục đích đơn giản hóa và tăng sự mềm dẻo, linh hoạt cho chương trình khi cần phải mở rộng.

Tác giả: xuanchien

Tran Xuan Chien. Japan Advanced Institute of Science and Technology - Japan. Senior Developer - NUS Technology.

1 thought on “Readonly – Writeonly Properties và Automatic Properties”

Gửi phản hồi

Mời bạn điền thông tin vào ô dưới đây hoặc kích vào một biểu tượng để đăng nhập:

WordPress.com Logo

Bạn đang bình luận bằng tài khoản WordPress.com Log Out / Thay đổi )

Twitter picture

Bạn đang bình luận bằng tài khoản Twitter Log Out / Thay đổi )

Facebook photo

Bạn đang bình luận bằng tài khoản Facebook Log Out / Thay đổi )

Google+ photo

Bạn đang bình luận bằng tài khoản Google+ Log Out / Thay đổi )

Connecting to %s