2009-08-03 30 views
19

Tôi đã tái cấu trúc mã nguồn của dự án mà tôi hiện đang sử dụng để các lớp/giao diện không hữu ích ngoài giới hạn của hội đồng phải được khai báo là nội bộ (chứ không phải là công khai) . Nhưng tôi đã chạy vào một vấn đề với đoạn mã sau:Làm cách nào để thực hiện các thành viên của các giao diện nội bộ

internal interface IFirstInterface 
{ 
    ... 
} 

internal interface ISecondInterface 
{ 
    IFirstInterface First{ get; } 
    ... 
} 

public class Implementer : ISecondInterface 
{ 
    public IFirstInterface First {get; private set;} 
    ... 
} 

Câu hỏi của tôi:

  1. Tại sao các thành viên của giao diện nội bộ đã được thực hiện công khai? Nếu bạn triển khai giao diện trên một lớp nội bộ, thì các thành viên được triển khai có phải là nội bộ không? Đây không phải là một vấn đề lớn vì các thành viên giao diện sẽ không được truy cập công khai, vì lớp đó là nội bộ. Nó chỉ có vẻ phản trực giác.

  2. Vấn đề chính là với kịch bản nêu trên kể từ khi tôi không thể có một getter công cộng cho IFirstInterface vì nó là tự nhận là một giao diện tức là nội tôi nhận được lỗi sau từ trình biên dịch:

không phù hợp khả năng tiếp cận : bất động sản gõ 'IFirstInterface' là ít truy cập hơn tài sản 'Implementer.First'

là ther e cách nào xung quanh điều này?

Lưu ý: Tôi nhận ra rằng có thể có ít giá trị trong bài tập tái cấu trúc này nhưng tôi nghĩ đó là cách tốt để tôi hiểu sâu hơn về tác động của công cụ sửa đổi nội bộ.

+0

Nếu nó một lựa chọn, bạn có thể khắc phục những hạn chế của phương pháp giao diện đang được công chúng bằng cách sử dụng một lớp cơ sở trừu tượng để thay thế. –

Trả lời

45

Chỉ cần lưu ý - mã bạn đã thực sự cung cấp không biên dịch, vì Implementer là một lớp nội bộ. Sự cố xảy ra khi công khai Implementer.

Cách vòng này là sử dụng giao diện thực hiện rõ ràng:

public class Implementer : ISecondInferface 
{ 
    private IFirstInterface first; 
    IFirstInterface ISecondInterface.First { get { return first; } } 
} 

Bạn không thể có setter trong đó, bởi vì bạn đang thực hiện một cách rõ ràng giao diện mà không định nghĩa setter. Bạn thể làm điều này như một sự thay thế:

public class Implementer : ISecondInterface 
{ 
    internal IFirstInterface First { get; private set; } 
    IFirstInterface ISecondInterface.First { get { return First; } } 
} 

Nó không may rằng giao diện nội bộ có thành viên nào - nó những điều phức tạp như thế này. Nó sẽ là lạ cho một giao diện công cộng để có một thành viên nội bộ (những gì nó sẽ là nội bộ để - người thực hiện hoặc người khai báo?) Nhưng đối với giao diện nội bộ nó làm cho rất nhiều ý nghĩa hơn.

+0

Ah, đúng. Tôi sẽ chỉnh sửa câu hỏi của tôi để ít gây nhầm lẫn cho người đọc. Cảm ơn! – jpoh

10

Tại sao các thành viên của giao diện nội bộ phải được triển khai công khai?

Khi bạn xác định giao diện, bạn không xác định cấp truy cập cho các thành viên, vì tất cả thành viên giao diện là public. Ngay cả khi giao diện như vậy là internal, các thành viên vẫn được coi là public. Khi bạn thực hiện một triển khai ngầm định của một thành viên như vậy, chữ ký phải phù hợp, vì vậy nó cần phải là public.

Về lộ getter, tôi sẽ đề nghị làm một rõ ràng thực hiện của giao diện thay vào đó, và tạo ra một tài sản internal để lộ giá trị:

internal IFirstInterface First { get; private set; } 

IFirstInterface ISecondInterface.First 
{ 
    get { return this.First; } 
} 
7

Tôi biết bài này là một vài tuổi nhưng tôi nghĩ rằng nó đáng chú ý là bạn có thể thực hiện một giao diện nội bộ trên một lớp công chúng, xem các liên kết sau đây:

http://forums.create.msdn.com/forums/p/29808/167820.aspx
http://msdn.microsoft.com/en-us/library/aa664591%28VS.71%29.aspx

Một ví dụ từ liên kết đầu tiên:


internal interface ISecretInterface 
{ 
    string Property1 { get; } 
} 

public class PublicClass : ISecretInterface 
{ 
    // class property 
    public string Property1 
    { 
     get { return "Foo"; } 
    } 

    // interface property 
    string ISecretInterface.Property1 
    { 
     get { return "Secret"; } 
    } 
} 
+0

Câu trả lời của bạn từ năm 2011 khác với hai câu trả lời từ năm 2009 như thế nào? –

+2

Thành thật mà nói tôi không biết và tôi có thể thấy lý do tại sao tôi có thể thêm nó mặc dù tôi nhớ làm điều đó. Nó không thêm bất cứ điều gì và tôi đã cố gắng để tìm ra nó bằng cách nhìn vào lịch sử sửa đổi để xem nếu có một đầu mối nhưng vẫn không có gì. Có lẽ tôi đã có một ngày câm. – Robert

+0

Vì lý do nào đó, câu trả lời này dễ dàng hơn cho tôi so với những câu trả lời trước đó bởi vì lời giải thích ở đầu câu trả lời giải quyết tình huống của tôi và khớp với những gì tôi đã Google. Vì vậy, cảm ơn vì đã nêu rõ rằng các lớp học công cộng có thể thực hiện các giao diện nội bộ theo cách dễ dàng tiêu thụ ;-). – binki

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