2010-03-29 39 views

Trả lời

29

Loại không thay đổi là loại thuộc tính của nó chỉ có thể được đặt lúc khởi tạo. Khi một đối tượng được tạo, không có gì có thể được thay đổi nữa. Một tài sản bất biến chỉ đơn giản là một tài sản chỉ đọc.

Trong ví dụ sau, ImmutableType là loại không thay đổi với một thuộc tính Test. Kiểm tra là thuộc tính chỉ đọc. Nó chỉ có thể được thiết lập lúc xây dựng.

class ImmutableType 
{ 
    private readonly string _test; 
    public string Test 
    { 
     get { return _test; } 
    } 

    public ImmutableType(string test) 
    { 
     _test = test; 
    } 
} 

cũng Xem: The Wikipedia article, và some StackOverflow questions về chủ đề này.

+4

Bạn có thể thực thi bất biến chống lại các thay đổi trong tương lai bằng cách thêm tiền tố _test với chỉ đọc. Than ôi, đáng tiếc là không có bất động sản tự động bất biến trong C#. –

+0

@Sam: Cảm ơn, đã cập nhật ví dụ. – fretje

+3

Điều này sẽ phức tạp hơn một chút khi thuộc tính của bạn là loại tham chiếu. Định nghĩa, sau đó, không thay đổi có thể được hiểu là tham chiếu * là bất biến _or_ * đồ thị đối tượng * là không thay đổi (tùy theo nhu cầu của bạn, nhưng thường là sau này - xem bài viết Wiki). –

4

fretje là chính xác. Ví dụ phổ biến nhất của loại không thay đổi là đối tượng string trong C#. Đây là toàn bộ lý do mà tồn tại StringBuilder.

3

Ngoài câu trả lời của @ fretje ở trên, trong C# 6 và sau đó, getter-only auto properties hiện đã được triển khai, cho phép các thuộc tính tự động không thay đổi mà không cần trường hậu thuẫn rõ ràng hơn private readonly. Mã tương đương sẽ được viết tắt là:

class ImmutableType 
{ 
    public string Test 
    { 
     get; // No Set at all, not even a private set. 
    } 

    public ImmutableType(string test) 
    { 
     Test = test; // The compiler understands this and initializes the backing field 
    } 
} 

Lưu ý rằng private set (gần nhất với tính bất biến có thể nhận được sử dụng các thuộc tính tự động trong các phiên bản trước đó của C#) chỉ cung cấp một đóng gói hạn chế của sự thay đổi đối với tài sản từ bên trong cùng lớp, và do đó không phải là thực sự bất biến:

public string Test 
{ 
    get; 
    private set; // Not immutable, since this is still mutable from within the class 
} 

Thông tin thêm về tính bất biến

Như những người khác đã nói, một immutable Property là một tài sản không thể thay đổi khi nó đã được thiết lập. Việc thiết lập 'giá trị duy nhất' thường được thực hiện trong hàm tạo.

An immutable Type là loại nơi tất cả các thuộc tính và trường bên ngoài không thể thay đổi - ví dụ loại "Bản ghi" ban đầu được lên lịch cho C# 7 (hopefully now 8) có thể là loại không thay đổi. Các ví dụ khác về Loại không thể loại là Tuples và tất cả anonymous classes.

Trường không thể thay đổi phải đủ điều kiện với từ khóa readonly trong C# - điều này được thực thi bởi trình biên dịch để đảm bảo rằng không có mã nào khác cố thay đổi trường bên ngoài hàm tạo.

Bất cứ nơi nào có thể, bất biến của trường, biến và thuộc tính được coi là thực hành tốt, vì điều này làm giảm diện tích bề mặt của lỗi (vì trường đại diện trạng thái của đối tượng, ngăn thay đổi trường giảm số lượng trạng thái).

Lợi ích của bất biến là đặc biệt quan trọng trong các chương trình đa luồng, trong đó hai hoặc nhiều luồng đồng thời truy cập cùng một đối tượng. Vì nhiều luồng đọc đồng thời có thể truy cập một cách an toàn giá trị của một trường hoặc thuộc tính, lập trình viên không cần quan tâm đến các vấn đề an toàn luồng liên quan đến việc thay đổi trường bằng các luồng khác.

Một nhược điểm chung của bất biến khi xử lý các đối tượng phức tạp bao gồm nhiều đối tượng sáng tác, là toàn bộ biểu đồ cần được xây dựng 'một lần', có thể dẫn đến mã lộn xộn.Một giải pháp phổ biến ở đây là sử dụng Builder pattern làm giàn giáo, cho phép biểu diễn tạm thời, có thể thay đổi được xây dựng theo các bước và sau đó là đối tượng cuối cùng, không thay đổi được thu được trong bước .Build() cuối cùng.

Các vấn đề liên quan