Видимість класу просто простору імен у C # /. NET?


87

У C #, чи можете ви зробити клас видимим лише у власному просторі імен, не живучи в іншій збірці? Це здається корисним для типових допоміжних класів, які не слід використовувати в інших місцях. (тобто те, що Java називає приватно-приватними класами)


Я не розумію вашого запитання. Я видалив свої відповіді, бо ви не мали на увазі „внутрішній”?
Zyphrax

3
@nos: ви шукаєте еквівалент видимості Java на рівні пакета?
Джон Сондерс,

Відповіді:



80

Ви можете створювати класи, internalале це лише заважає будь-кому за межами збірки використовувати клас. Але вам все одно потрібно зробити окрему збірку для кожного простору імен, з яким ви хочете це зробити. Я припускаю, що саме тому ви не хотіли б цього робити.

Отримання компілятора C # для забезпечення видимості простору імен

Тут є стаття ( Видимість простору імен у C # ), де показано метод використання часткових класів як форми "фальшивого простору імен", який вам може бути корисним.

Автор зазначає, що це не працює ідеально, і він обговорює недоліки. Основна проблема полягає в тому, що дизайнери C # спроектували C # не працювати таким чином. Це значно відхиляється від очікуваних практик кодування в C # /. NET, що є однією з найбільших переваг .NET Frameworks.

Це акуратний фокус ... тепер не робіть цього.


1
Щойно знайшов приклад:System.Net.Mime.MediaTypeNames.Application
Bitterblue

У статті йдеться про те, що перед кожним викликом потрібно вводити ім'я "простору імен", але це не потрібно для C # 6 "з використанням статики". Ви можете зробити "простір імен" статичним частковим класом, а потім у коді клієнта написати "using static"
Пумко,

@Pumkko Клас не повинен бути статичним, щоб мати можливість використовувати оператор 'using static', хоча, якщо ви використовуєте його як простір імен, це все одно має бути.
Fuzzy Logic

21

внутрішня - це конфіденційність збірки (строго кажучи модуля). Це не впливає на видимість простору імен.

Єдиний спосіб досягти конфіденційності класу від інших класів в рамках тієї самої збірки - це клас бути внутрішнім класом.

На даний момент, якщо клас приватний, він невидимий для будь-чого, що не входить до цього класу або до самого зовнішнього класу.

Якщо захищений, його бачать усі, хто міг бачити його як приватний, але також видно для підкласів зовнішнього класу.

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
    }
}

По суті, єдиним способом досягти того, що ви бажаєте, є використання зовнішнього класу як форми простору імен та обмеження в межах цього класу.


@ShuggyCoUK: публічний клас Sub: Зовнішній повинен бути запечатаний публічний клас Sub: Зовнішній ??? +1, хоча ... це працює для мене
IAbstract

0

Якщо у вас є одна збірка, ви можете визначити стільки просторів імен у цій збірці, скільки завгодно, але незалежно від того, який модифікатор ви застосовуєте в IDE, ви завжди зможете бачити класи в інших просторах імен.


0

Не впевнений, чи це можливо безпосередньо, але кілька хороших способів підробити це буде:

1) Нехай класи, яким потрібен такий матеріал, успадковуються від одного класу, який має допоміжний клас як внутрішній клас.

2) Використовуйте методи розширення, а потім посилайтеся лише на методи розширення в просторі імен.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.