Tại sao C # cho phép các thuộc tính trong giao diện?


47

Trong C #, đoạn mã sau là hợp lệ

interface I{
    int property{get;set;}
}

Điều đó không có ý nghĩa gì với tôi. Điều này dường như phá vỡ một trong những nguyên tắc quan trọng nhất của giao diện: thiếu trạng thái (nói cách khác, không có trường). Không phải tài sản tạo ra một lĩnh vực tư nhân ngầm? Điều đó có thực sự tệ cho giao diện không?


12
Là thiếu trạng thái một trong những nguyên tắc của việc thực hiện giao diện ? Đối với tôi, một giao diện là một cách để xác định hợp đồng, tức là nếu một lớp thực hiện giao diện đó, thì nó có tất cả các phương thức và thuộc tính được định nghĩa trong hợp đồng.
Florian Margaine

4
Một thuộc tính chỉ là một phương thức get và một phương thức thiết lập. Vì các giao diện chỉ là một danh sách các phương thức bạn phải thực hiện, nên việc các giao diện có thể có chúng là điều đương nhiên.
Doval

1
@FlorianMargaine Chắc chắn khái niệm hợp đồng là nguyên tắc quan trọng nhất của giao diện, nhưng thiếu trạng thái cũng rất quan trọng. Điều này giúp giữ cho nó tách biệt với một lớp trừu tượng. IE trong Java 8 cuối cùng là sự khác biệt lớn duy nhất giữa các giao diện và các lớp trừu tượng.
Phục hồi lại

2
Bởi vì nó không phải là một lĩnh vực. Xem tại sao giao diện C # không thể chứa các trường?

2
@Doval: Điều tự nhiên là một giao diện khai báo các phương thức như vậy, nhưng không phải là nó thực hiện chúng.
Giorgio

Câu trả lời:


65

Tôi nghĩ phần khó hiểu là nếu bạn viết int Property { get; set; }bên trong một lớp, thì đó là một thuộc tính tự động với trường sao lưu ngầm.

Nhưng nếu bạn viết chính xác điều tương tự trong một giao diện, thì đó không phải là thuộc tính tự động , nó chỉ tuyên bố rằng thuộc tính đó là một phần của giao diện và bất kỳ loại nào thực hiện giao diện đó đều phải chứa thuộc tính đó (là thuộc tính tự động hay không ), nhưng nó không tạo ra trường sao lưu.

Một cách để thấy sự khác biệt là viết int Property { get; }: điều này hợp lệ trong một giao diện và khai báo một thuộc tính chỉ có một getter, nhưng không có setter. Nhưng nó sẽ không biên dịch trong một lớp (trừ khi bạn đang sử dụng C # 6.0), vì thuộc tính tự động phải có bộ cài đặt.


18

Xác định thuộc tính như bạn đã hiển thị giống như xác định các phương thức int GetProperty()void SetProperty(int i). Thuộc tính là tay ngắn mạnh mẽ trong C #.

Một thuộc tính không hoàn toàn tạo ra một trường riêng trong C #. Đó là cách triển khai mặc định của một auto-propertyví dụ public string MyString { get; set;}- tuy nhiên, một thuộc tính xác định logic tùy chỉnh trong getphương thức không tạo ra một trường riêng ẩn.

Cuối cùng, vì các giao diện liên quan đến API công cộng , sẽ có vấn đề gì nếu việc triển khai thuộc tính giao diện dựa trên một trường riêng - ẩn hay nói cách khác? Điều đó được ẩn từ người tiêu dùng của giao diện bất kể.


À ... tôi không nhận ra nó chỉ xảy ra đối với các thuộc tính tự động, và vì bạn phải ghi đè lên nó, điều đó có ý nghĩa. Nhưng nếu giao diện là để tạo một biến riêng tư nội bộ, thì những người triển khai sẽ không có quyền truy cập vào nó - một vấn đề rõ ràng.
Phục hồi lại

9
Nếu bạn xác định một thuộc tính trong giao diện C #, thì việc triển khai thuộc tính đó được để lại cho lớp triển khai - họ có thể biến nó thành thuộc tính tự động hoặc xác định logic tùy chỉnh khi chúng thấy phù hợp. Không có trường nào được thêm vào giao diện .
Tây Ban Nha

10

Thuộc tính phương thức! Một trường sao lưu sẽ được thêm vào lớp thực hiện giao diện (theo cách thủ công hoặc thông qua thuộc tính tự động).


Đôi khi sẽ không có trường sao lưu. Mặc dù sẽ rất hiếm khi xác định cả get và set và không có trường sao lưu cho nó.
Stephen

Thuộc tính +1 là phương thức! Đúng! Tôi thích viết Propertymethods nhưng đồng nghiệp xem xét mã không thấy như vậy và chúng tôi thực sự bỏ lỡ cơ hội cho một số đóng gói biểu cảm tốt đẹp trong các chương trình của chúng tôi.
radarbob

Những "phương thức thuộc tính" đó phải nhanh chóng, giống như không tìm kiếm DB hay bất cứ thứ gì. Có một hợp đồng ngụ ý rằng việc truy cập tài sản nhanh, các phương thức Get * có thể chậm.
Trey Mack
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.