Khả năng hiển thị lớp chỉ không gian tên trong C # /. NET?


87

Trong C #, bạn có thể làm cho một lớp chỉ hiển thị trong không gian tên riêng của nó mà không sống trong một hội đồng khác không? Điều này có vẻ hữu ích cho các lớp trợ giúp điển hình không nên sử dụng ở những nơi khác. (tức là những gì Java gọi các lớp gói-riêng)


Tôi không hiểu câu hỏi của bạn. Tôi đã xóa câu trả lời của mình vì ý bạn không phải là "nội bộ"?
— Zyphrax

3
@nos: bạn đang tìm kiếm khả năng hiển thị cấp độ gói tương đương của java?
— John Saunders

Câu trả lời:



80

Bạn có thể tạo các lớp internalnhưng điều này chỉ ngăn không cho bất kỳ ai bên ngoài assembly sử dụng lớp. Nhưng bạn vẫn phải tạo một assembly riêng cho từng vùng tên mà bạn muốn thực hiện việc này. Tôi cho rằng đó là lý do tại sao bạn không muốn làm điều đó.

Bắt trình biên dịch C # để thực thi khả năng hiển thị không gian tên

Có một bài báo ở đây ( Khả năng hiển thị không gian tên trong C # ) chỉ ra một phương pháp sử dụng các lớp một phần như một dạng "không gian tên giả" mà bạn có thể thấy hữu ích.

Tác giả chỉ ra rằng điều này không hoạt động hoàn hảo và anh ấy thảo luận về những thiếu sót. Vấn đề chính là các nhà thiết kế C # đã thiết kế C # không hoạt động theo cách này. Điều này khác rất nhiều so với các thực hành mã hóa dự kiến ​​trong C # /. NET, đây là một trong những lợi thế lớn nhất của .NET Framework.

Đó là một mẹo nhỏ ... bây giờ đừng làm điều đó.


1
Chỉ cần tìm thấy một ví dụ:System.Net.Mime.MediaTypeNames.Application
— Bitterblue

Bài báo nói rằng bạn phải đặt tiền tố cho mọi cuộc gọi bằng tên "không gian tên" của mình, nhưng bạn không cần điều đó với C # 6 "sử dụng tĩnh". Bạn có thể làm cho "namespace" một lớp học phần tĩnh và sau đó trong mã khách hàng ghi "sử dụng tĩnh"
— Pumkko

@Pumkko Lớp không cần phải tĩnh để có thể sử dụng câu lệnh 'using static', mặc dù nếu bạn đang sử dụng nó như một không gian tên thì nó vẫn phải như vậy.
— Logic mờ

21

nội bộ là sự riêng tư của assembly (nói đúng ra là mô-đun). Nó không ảnh hưởng đến khả năng hiển thị không gian tên.

Cách duy nhất để đạt được sự riêng tư của một lớp với các lớp khác trong cùng một assembly là để một lớp là một lớp bên trong.

Tại thời điểm này, nếu lớp là private thì nó sẽ vô hình với bất kỳ thứ gì không có trong lớp đó hoặc chính lớp ngoài.

Nếu được bảo vệ, nó sẽ hiển thị cho tất cả những người có thể nhìn thấy nó khi ở chế độ riêng tư nhưng cũng hiển thị cho các lớp con của lớp bên ngoài.

public class Outer
{
    private class Hidden     { public Hidden() {} }
    protected class Shady    { public Shady() {} }
    public class Promiscuous { public Promiscuous() {} }
}

public class Sub : Outer
{
    public Sub():base() 
    {
        var h = new Hidden();      // illegal, will not compile
        var s = new Shady();       // legal
        var p = new Promiscuous(); // legal
    }
}

public class Outsider 
{
    public Outsider() 
    {
        var h = new Outer.Hidden();      // illegal, will not compile
        var s = new Outer.Shady()        // illegal, will not compile
        var p = new Outer.Promiscuous(); // legal
    }
}

Về bản chất, cách duy nhất để đạt được những gì bạn mong muốn là sử dụng lớp ngoài như một dạng không gian tên và hạn chế bên trong lớp đó.


@ShuggyCoUK: public class Sub: Bên ngoài nên được niêm phong công cộng Class Sub: Outer ??? +1 mặc dù ... nó hiệu quả với tôi
— IAbstract

0

Nếu bạn có một hợp ngữ duy nhất, bạn có thể xác định bao nhiêu không gian tên trong hợp ngữ đó tùy thích nhưng bất kể bạn áp dụng công cụ sửa đổi nào trong IDE, bạn sẽ luôn có thể thấy các lớp trong không gian tên khác.


0

Không chắc liệu nó có thể trực tiếp được hay không, nhưng một số cách tốt để giả mạo nó sẽ là:

1) Có các lớp cần loại nội dung này kế thừa từ một lớp duy nhất có lớp trợ giúp là lớp bên trong.

2) Sử dụng các phương thức mở rộng và sau đó chỉ tham chiếu các phương thức mở rộng trong không gian tên.

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 cookie và Chính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.