2013-02-21 34 views
10

Tôi có một lớp trừu tượng trong một API được sử dụng bởi các phương thức trong một assembly khác. Lớp có một enum lồng nhau được xác định bên trong nó, một chút như thế này:Giao diện không thể khai báo các loại

abstract public class Thing 
{ 
    public enum Status { Accepted, Denied, Pending }; 
    abstract public Status status { get; private set; } 
    etc... 
} 

Sau đó tôi quyết định nó sẽ là một thiết kế tốt hơn nếu Thing là một giao diện. Nhưng tôi không thể làm điều này:

public interface Thing 
{ 
    enum Status { Accepted, Denied, Pending }; 
    Status status { get; } 
    etc... 
} 

Điều này tạo ra thông báo lỗi "Giao diện không thể khai báo loại". Tuy nhiên, nếu tôi di chuyển định nghĩa của enum bên ngoài giao diện, trước tiên tôi sẽ phá vỡ đóng gói (loại trạng thái thực sự thuộc về Thing và vô nghĩa một mình) và quan trọng hơn tôi sẽ phải đi và sửa đổi mã trong nhiều hội đồng khác sử dụng nó. Bạn có thể nghĩ ra giải pháp nào không?

+0

Nếu bạn lo lắng về việc * phá vỡ * (Bạn không thể đóng gói các thành viên dữ liệu trong giao diện bằng cách đóng gói), bạn nên để nguyên 'Thing' làm lớp. Không có gì sai với lớp cơ sở trừu tượng của bạn. –

+0

tìm thấy một số địa điểm khác mà câu hỏi này được đặt ra, nhận xét này về ý kiến ​​này có một số lựa chọn tốt. http://social.msdn.microsoft.com/forums/en-US/csharpgeneral/thread/14beb8d1-63d9-42f7-b036-eb9ebb106d08 về cơ bản, bạn có thể khai báo enum ở nơi khác hoặc sử dụng lớp học thay thế của một giao diện .... và đó là về nó. Không có cách nào để làm chính xác những gì bạn đang cố gắng làm, điều đó thật đáng tiếc. – Nevyn

+4

Đối số "đóng gói" không hợp lý với tôi và tôi khuyên bạn nên loại bỏ loại lồng nhau công khai. Nếu nó có thể được tiếp xúc với thế giới, sau đó đối xử với nó như vậy. –

Trả lời

13

Khi lỗi cho biết, bạn chỉ cần kéo định nghĩa của Status ra ngoài giao diện. Tôi hiểu rằng nó phá vỡ đóng gói, nhưng thực sự không có cách nào xung quanh điều này. Tôi đề nghị bạn thay đổi tên của Status thành một cái gì đó cho thấy một mối quan hệ mạnh mẽ để Thing - ThingStatus nên làm các trick.

enum ThingStatus { Accepted, Denied, Pending }; 

public interface Thing 
{ 
    ThingStatus status { get; } 
    etc... 
} 
3

Ồ, giải pháp là sử dụng lớp trừu tượng nếu bạn cần thực hiện như vậy. Các lớp trừu tượng không phải là một thiết kế tồi và chắc chắn hữu ích trong các tình huống như thế này.

Nếu bạn nhấn mạnh vào việc sử dụng giao diện, tôi e rằng bạn phải đi với giải pháp từ p.s.w.g và phá vỡ một hoặc hai quy tắc (tất cả chỉ là hướng dẫn).

1

abstract lớp và interface là những thứ khác nhau. Lớp abstarct trừu tượng, cao hơn mô hình miền và giao diện của bạn là hợp đồng (hành vi) của thực thể tên miền của bạn. Bạn có thể sử dụng cả hai trong giải pháp của bạn khi cần thiết. Trong kịch bản cụ thể status không phải là hành vi nó chỉ là trạng thái của thực thể. Tôi nghĩ lớp trừu tượng là sự lựa chọn đáng tin cậy hơn.

+0

Cảm ơn quan điểm này, đó là điều cần suy nghĩ. Là một điểm đáng chú ý, lưu ý cách các lớp trừu tượng được sử dụng như các giao diện trong các ngôn ngữ không có giao diện như là một phần của cú pháp của chúng (C++ là ví dụ rõ ràng). –

+0

@KlitosKyriacou Sử dụng lớp trừu tượng làm giao diện có thể đạt được bằng cách tuyên bố tất cả các thành viên là trừu tượng. Nhưng điều này là không chính xác giống nhau trong C#. –

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