2012-10-19 20 views
5

Tôi đang tìm cách xác định lớp lồng nhau có thể truy cập được vào lớp chứa và lớp bên ngoài, nhưng tôi muốn kiểm soát sự khởi tạo của lớp lồng nhau, các cá thể của lớp container có thể tạo ra các cá thể mới của lớp lồng nhau.Cho phép truy cập nhưng ngăn chặn việc tạo lớp lồng nhau bởi các lớp bên ngoài

Mã tục hy vọng sẽ chứng minh điều này:

public class Container 
{ 
    public class Nested 
    { 
     public Nested() { } 
    } 

    public Nested CreateNested() 
    { 
     return new Nested(); // Allow 
    } 
} 

class External 
{ 
    static void Main(string[] args) 
    { 
     Container containerObj = new Container(); 
     Container.Nested nestedObj; 

     nestedObj = new Container.Nested();  // Prevent 
     nestedObj = containerObj.CreateNested(); // Allow 

    } 
} 

Nested phải được công khai để cho nó có thể truy cập bằng cách External. Tôi đã thử làm cho hàm tạo cho bảo vệ Nested, tuy nhiên điều đó ngăn cản Container tạo các cá thể, vì Container không phải là lớp cơ sở là Nested. Tôi có thể thiết lập các nhà xây dựng cho Nested để internal, nhưng tôi đang tìm cách để ngăn chặn truy cập vào constructor bởi tất cả các lớp bên ngoài, bao gồm cả những người trong cùng một hội đồng. Có cách nào để làm việc này không?

Nếu điều này không thể đạt được thông qua công cụ sửa đổi truy cập, tôi tự hỏi liệu tôi có thể ném ngoại lệ trong vòng Nested() hay không. Tuy nhiên, tôi không biết cách kiểm tra ngữ cảnh trong đó new Nested() được gọi.

Trả lời

6

Làm thế nào để trừu tượng hóa qua giao diện?

public class Container 
{ 
    public interface INested 
    { 
     /* members here */ 
    } 
    private class Nested : INested 
    { 
     public Nested() { } 
    } 

    public INested CreateNested() 
    { 
     return new Nested(); // Allow 
    } 
} 

class External 
{ 
    static void Main(string[] args) 
    { 
     Container containerObj = new Container(); 
     Container.INested nestedObj; 

     nestedObj = new Container.Nested();  // Prevent 
     nestedObj = containerObj.CreateNested(); // Allow 

    } 
} 

Bạn cũng có thể làm điều tương tự với một cơ sở lớp trừu tượng:

public class Container 
{ 
    public abstract class Nested { } 
    private class NestedImpl : Nested { } 
    public Nested CreateNested() 
    { 
     return new NestedImpl(); // Allow 
    } 
} 

class External 
{ 
    static void Main(string[] args) 
    { 
     Container containerObj = new Container(); 
     Container.Nested nestedObj; 

     nestedObj = new Container.Nested();  // Prevent 
     nestedObj = containerObj.CreateNested(); // Allow 

    } 
} 
+0

Dường như làm việc! Cảm ơn! –

1

Nó là không thể khai báo lớp theo cách như vậy. Tôi nghĩ rằng cách tốt nhất để bạn có thể khai báo lớp là riêng tư và hiển thị lớp học thông qua giao diện công khai:

class Program 
{ 
    static void Main(string[] args) 
    { 
     // new S.N(); does not work 
     var n = new S().Create(); 
    } 
} 

class S 
{ 
    public interface IN 
    { 
     int MyProperty { get; set; } 
    } 
    class N : IN 
    { 
     public int MyProperty { get; set; } 
     public N() 
     { 

     } 
    } 

    public IN Create() 
    { 
     return new N(); 
    } 
}