Các giá trị kiểm tra độ chính xác khác có thể có trong trình thiết lập có lý do cơ bản hơn để thích các thuộc tính cho các biến công cộng không?Tại sao lại chọn Thuộc tính cho các biến công khai?
Trả lời
Chúng tôi đã có chủ đề này trước nhưng tôi không thể tìm thấy bất kỳ điều gì ngay bây giờ.
Tóm lại: nhu cầu của bạn có thể thay đổi: hiện tại không có sự kiểm tra sự lành mạnh nào, bạn có thể cần phải kiểm tra trong tương lai. Tuy nhiên, nếu bạn thay đổi trường công khai thành thuộc tính, điều này sẽ phá vỡ tính tương thích nhị phân: mọi khách hàng sử dụng mã/thư viện của bạn sẽ phải biên dịch lại.
Đây là xấu vì nó có khả năng tốn nhiều tiền.
Sử dụng các thuộc tính ngay từ đầu tránh được sự cố này. Điều này thậm chí còn đếm cho mã không phải là một phần của thư viện. Tại sao? Bởi vì bạn không bao giờ biết: mã (ngay cả khi tên miền cụ thể cao!) Có thể hữu ích để bạn muốn cấu trúc lại nó thành một thư viện. Quá trình tái cấu trúc này rõ ràng được thực hiện dễ dàng hơn nhiều nếu bạn đã sử dụng các thuộc tính thay cho các trường công cộng/được bảo vệ.
Ngoài ra, văn bản tài sản công cộng rất dễ dàng trong C# 3.0 vì bạn chỉ có thể sử dụng các thuộc tính tự động thực hiện, giúp bạn tiết kiệm khá nhiều mã:
public DataType MyProperty { get; set; }
sẽ thực hiện các lĩnh vực sao lưu cần thiết và getter/setter mã cho bạn.
Tôi sẽ thêm ghi chú cá nhân: Hành vi của .NET về vấn đề này hơi lười. Trình biên dịch chỉ có thể thay đổi các trường công khai thành các thuộc tính khi đang di chuyển, do đó tránh được vấn đề. VB6 đã làm điều này cho các lớp tiếp xúc COM và tôi thấy hoàn toàn không có lý do gì cho VB.NET và C# không làm như vậy. Có lẽ ai đó trong nhóm biên dịch (Jared?) Có thể bình luận về điều này.
Bỏ qua câu hỏi nên có nhiều lý do tại sao Trình biên dịch không thể thực hiện việc này. Có 2 lý do đến ngay lập tức. 1) tên và 2) gọi một thuộc tính không giống như truy cập một trường (hiệu suất, ref và out). Thật không may, không có đủ không gian ở đây để thực sự bình luận – JaredPar
(tiếp theo) và chủ đề được đóng lại. Nhưng phiên bản ngắn là người dùng đang yêu cầu một mục và bạn đang cho họ một sự thay thế không bằng nhau. Người dùng thường không hài lòng khi bạn làm điều đó. – JaredPar
Cảm ơn câu trả lời, Jared. :-) –
Jeff Atwood has blogged about it:
Có nhiều lý do hợp lệ để làm cho một tài sản tầm thường, chính xác như mô tả ở trên:
- Reflection công trình khác nhau trên các biến so với tài sản, vì vậy nếu bạn dựa vào phản xạ, nó dễ dàng hơn để sử dụng tất cả các thuộc tính.
- Bạn không thể databind chống lại một biến.
- Thay đổi biến thành thuộc tính là a breaking change.
Thật đáng tiếc là có quá nhiều ma sát vô nghĩa giữa các biến và thuộc tính; hầu hết thời gian họ làm điều tương tự. Kevin Dente đề xuất một chút cú pháp mới mà sẽ cung cấp cho chúng tôi là tốt nhất của cả hai thế giới:
public property int Name;
Tuy nhiên, nếu sự phân biệt giữa biến và bất động sản là một vấn đề đang diễn ra như vậy, tôi tự hỏi, nếu một giải pháp triệt để hơn là theo thứ tự. Chúng ta không thể mương biến hoàn toàn có lợi cho tài sản? Thuộc tính không thực hiện chính xác điều tương tự như biến, nhưng với kiểm soát chi tiết hơn về khả năng hiển thị?
Sử dụng thuộc tính làm cho mã của bạn hướng đối tượng hơn. Bằng cách đặt biến thành viên ở chế độ công khai, bạn đang hiển thị việc triển khai của mình.
Xem thêm link này từ Programming Guide
C# 's Thay đổi một trường để một tài sản trong tương lai được coi là một sự thay đổi phá vỡ. Các lĩnh vực được coi là chi tiết thực hiện của các lớp học và phơi bày chúng công khai phá vỡ đóng gói.
Nó chỉ là một thay đổi phá vỡ nếu mã gọi điện thoại không thể được biên dịch lại, hầu hết thời gian bạn sở hữu mã người gọi và nó được biên dịch bởi cùng một hệ thống xây dựng. Do đó, đây không phải là vấn đề đối với hầu hết các khía cạnh của nhóm .NET framework. –
@Ian Ringrose: Nó không hoàn toàn tương thích với nguồn. Ví dụ, mã của bạn có thể làm một 'ref obj.MyField'. Bạn không thể thay đổi 'MyField' thành' MyProperty' mà không thay đổi nguồn. –
@Ian: Đó là một thay đổi đột phá - http://msdn.microsoft.com/en-us/library/ms182141 (VS.80).aspx – Cerebrus
Nếu bạn làm việc trong môi trường đóng - bạn không phát triển SDK, tất cả các lớp được sử dụng trong cùng một khuôn khổ dự án - không có sự khác biệt.
Đối số thông thường là "trong tương lai bạn có thể cần thực hiện kiểm tra các giá trị, vì vậy sẽ dễ dàng hơn với các thuộc tính". Tôi không mua nó chút nào.
Sử dụng các trường công khai dễ đọc hơn, ít trang trí hơn và dễ sử dụng hơn.
"Dễ sử dụng hơn?" Bằng cách nào? –
Có.
Hãy xem xét một biến số công cộng hiện đang giữ một chuỗi, bạn có thể chỉ cần đặt nó. Tuy nhiên, nếu bạn quyết định rằng biến công khai nên giữ một đối tượng mà nên được khởi tạo bằng một chuỗi thì bạn sẽ phải thay đổi tất cả mã của bạn bằng cách sử dụng đối tượng ban đầu của bạn. Nhưng nếu bạn đã sử dụng setter, bạn sẽ chỉ phải thay đổi setter để khởi tạo đối tượng với chuỗi được cung cấp.
Bạn cũng có thể bảo vệ ghi truy cập và cho phép truy cập đọc với một tài sản:
public int Version { get; private set; }
Điều này thực sự không biên dịch. Tôi nghĩ ý của bạn là: 'public int Version {get; bộ tư nhân; } ' –
Tóm lại:
- Bạn có thể kiểm soát acces (chỉ đọc,
WriteOnly, đọc/ghi) - Bạn có thể xác thực giá trị khi đặt một thuộc tính (kiểm tra trống ...)
- Bạn có thể xử lý bổ sung, chẳng hạn như khởi tạo lười biếng
- Bạn có thể thay đổi triển khai thực hiện cơ bản. Ví dụ: thuộc tính có thể được hỗ trợ bởi thành viên bây giờ, nhưng bạn có thể thay đổi nó để được hỗ trợ bởi hàng DB mà không cần vi phạm bất kỳ mã người dùng nào.
Một cách hiệu quả một phần của http://stackoverflow.com/questions/641619/when-should-you-use-a-field-rather-than-a-property và http://stackoverflow.com/questions/379041/những gì-là-tốt nhất-thực hành-cho-sử dụng-công-lĩnh vực/379057 - trong số những người khác. – tvanfosson