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


87

Можно ли в C # сделать класс видимым только в его собственном пространстве имен, не живя в другой сборке? Это кажется полезным для типичных вспомогательных классов, которые не следует использовать где-либо еще. (т.е. то, что Java называет частными пакетами классов)


Я не понимаю твоего вопроса. Я удалил свои ответы, потому что вы не имели в виду «внутренний»?
— Zyphrax 03

3
@nos: вы ищете эквивалент видимости на уровне пакета Java?
— Джон Сондерс,

Ответы:



80

Вы можете создавать классы, internalно это не позволяет никому за пределами сборки использовать этот класс. Но вам все равно нужно создать отдельную сборку для каждого пространства имен, с которым вы хотите это сделать. Я предполагаю, что именно поэтому вы не захотите этого делать.

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

Здесь есть статья ( Видимость пространства имен в C # ), в которой показан метод использования частичных классов в качестве формы «поддельного пространства имен», которое может оказаться полезным.

Автор отмечает, что это работает не идеально, и обсуждает недостатки. Основная проблема заключается в том, что разработчики C # разработали C # таким образом, чтобы он не работал. Это сильно отличается от ожидаемой практики кодирования в C # /. NET, что является одним из самых больших преимуществ .NET Framework.

Это изящный трюк ... не делай этого.


1
Только что нашел пример:System.Net.Mime.MediaTypeNames.Application
— Bitterblue

В статье говорится, что вы должны добавлять к каждому вызову префикс своего «пространства имен», но вам это не нужно с C # 6 «using static». Вы можете сделать «пространство имен» статическим частичным классом, а затем в клиентском коде написать «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.