Tôi muốn giải thích về một điểm cụ thể mà Eric Lippert đã đưa ra trong câu trả lời của mình và đặt sự chú ý vào một dịp đặc biệt mà không ai có thể chạm vào được. Eric nói:
[...] một nhiệm vụ hầu như luôn để lại giá trị vừa được gán trong một thanh ghi.
Tôi muốn nói rằng bài tập sẽ luôn để lại giá trị mà chúng tôi đã cố gán cho toán hạng bên trái của chúng tôi. Không chỉ "hầu như luôn luôn". Nhưng tôi không biết vì tôi chưa tìm thấy vấn đề này trong tài liệu này. Về mặt lý thuyết, đây có thể là một quy trình được thực hiện rất hiệu quả để "bỏ lại phía sau" và không đánh giá lại toán hạng bên trái, nhưng nó có hiệu quả không?
'Hiệu quả' có cho tất cả các ví dụ cho đến nay được xây dựng trong các câu trả lời của chủ đề này. Nhưng hiệu quả trong trường hợp thuộc tính và bộ chỉ mục sử dụng bộ truy cập get- và set? Không có gì. Xem xét mã này:
class Test
{
public bool MyProperty { get { return true; } set { ; } }
}
Ở đây chúng ta có một thuộc tính, thậm chí không phải là một trình bao bọc cho một biến riêng. Bất cứ khi nào được kêu gọi anh ta sẽ trở về đúng, bất cứ khi nào cố gắng thiết lập giá trị của mình, anh ta sẽ không làm gì cả. Vì vậy, bất cứ khi nào tài sản này được đánh giá, anh ta sẽ được trung thực. Hãy xem điều gì xảy ra:
Test test = new Test();
if ((test.MyProperty = false) == true)
Console.WriteLine("Please print this text.");
else
Console.WriteLine("Unexpected!!");
Đoán xem nó in cái gì? Nó in Unexpected!!
. Hóa ra, bộ truy cập thiết lập thực sự được gọi, không có gì. Nhưng sau đó, người truy cập get không bao giờ được gọi cả. Việc chuyển nhượng chỉ đơn giản là để lại false
giá trị mà chúng tôi đã cố gắng gán cho tài sản của chúng tôi. Và false
giá trị này là những gì câu lệnh if đánh giá.
Tôi sẽ kết thúc với một ví dụ thực tế khiến tôi phải nghiên cứu vấn đề này. Tôi đã tạo một bộ chỉ mục là một trình bao bọc thuận tiện cho một bộ sưu tập ( List<string>
) mà một lớp của tôi có một biến riêng.
Tham số được gửi tới bộ chỉ mục là một chuỗi, được coi là một giá trị trong bộ sưu tập của tôi. Trình truy cập get chỉ đơn giản trả về giá trị true hoặc false nếu giá trị đó tồn tại trong danh sách hay không. Do đó, bộ truy cập get là một cách khác để sử dụng List<T>.Contains
phương thức.
Nếu bộ truy cập tập hợp chỉ mục được gọi với một chuỗi làm đối số và toán hạng bên phải là một bool true
, anh ta sẽ thêm tham số đó vào danh sách. Nhưng nếu cùng một tham số được gửi đến người truy cập và toán hạng bên phải là một bool false
, thay vào đó anh ta sẽ xóa phần tử khỏi danh sách. Do đó, bộ truy cập đã được sử dụng như là một thay thế thuận tiện cho cả hai List<T>.Add
và List<T>.Remove
.
Tôi nghĩ rằng tôi đã có một "API" gọn gàng và gọn gàng trong danh sách với logic riêng của tôi được triển khai như một cổng. Với sự giúp đỡ của một người lập chỉ mục, tôi có thể làm nhiều việc với một vài tổ hợp phím. Chẳng hạn, làm thế nào tôi có thể thử thêm một giá trị vào danh sách của mình và xác minh rằng nó có trong đó không? Tôi nghĩ rằng đây là dòng mã duy nhất cần thiết:
if (myObject["stringValue"] = true)
; // Set operation succeeded..!
Nhưng như ví dụ trước đây của tôi đã chỉ ra, trình truy cập get được cho là để xem liệu giá trị thực sự có trong danh sách thậm chí không được gọi hay không. Các true
giá trị luôn được bỏ lại phía sau một cách hiệu quả phá hủy bất cứ logic tôi đã thực hiện trong get accessor tôi.