Widoczność klas obejmujących tylko przestrzeń nazw w C # / .NET?

87

Czy w języku C # można uczynić klasę widoczną tylko w jej własnej przestrzeni nazw bez przebywania w innym zestawie? Wydaje się to przydatne w przypadku typowych klas pomocniczych, których nie należy używać gdzie indziej. (czyli to, co Java nazywa prywatnymi klasami pakietu)

nr
źródło
Nie rozumiem twojego pytania. Usunąłem moje odpowiedzi, ponieważ nie miałeś na myśli „wewnętrznego”?
Zyphrax
3
@nos: czy szukasz odpowiednika widoczności na poziomie pakietu Java?
John Saunders

Odpowiedzi:

35

Nie sądzę, że to, czego chcesz, jest możliwe.

Steven Sudit
źródło
80

Możesz utworzyć klasy, internalale to uniemożliwia tylko osobom spoza zestawu korzystanie z klasy. Ale nadal musisz utworzyć oddzielny zestaw dla każdej przestrzeni nazw, z którą chcesz to zrobić. Zakładam, że dlatego nie chcesz tego robić.

Pobieranie kompilatora C # w celu wymuszenia widoczności przestrzeni nazw

W tym miejscu znajduje się artykuł ( Widoczność przestrzeni nazw w C # ), który przedstawia metodę używania klas częściowych jako formy „fałszywej przestrzeni nazw”, która może okazać się pomocna.

Autor zwraca uwagę, że to nie działa idealnie i omawia niedociągnięcia. Głównym problemem jest to, że projektanci C # zaprojektowali C # tak, aby nie działał w ten sposób. To znacznie odbiega od oczekiwanych praktyk kodowania w C # / .NET, co jest jedną z największych zalet .NET Framework.

To fajna sztuczka… teraz tego nie rób.

Robert Cartaino
źródło
1
Właśnie znalazłem przykład:System.Net.Mime.MediaTypeNames.Application
Bitterblue
Artykuł mówi, że musisz poprzedzić każde wywołanie nazwą „przestrzeni nazw”, ale nie jest to potrzebne w przypadku C # 6 „przy użyciu statycznego”. Możesz uczynić „przestrzeń nazw” statyczną klasą częściową, a następnie w kodzie klienta napisać „using static”
Pumkko
@Pumkko Klasa nie musi być statyczna, aby móc użyć instrukcji „using static”, chociaż jeśli używasz jej jako przestrzeni nazw, to i tak powinna być.
Fuzzy Logic
21

wewnętrzna to prywatność montażu (ściśle mówiąc modułu). Nie ma to wpływu na widoczność przestrzeni nazw.

Jedynym sposobem uzyskania prywatności klasy z innych klas w tym samym zestawie jest to, aby klasa była klasą wewnętrzną.

W tym momencie, jeśli klasa jest prywatna, jest niewidoczna dla niczego, co nie jest w tej klasie ani w samej klasie zewnętrznej.

Jeśli jest chroniony, jest widoczny dla każdego, kto może go zobaczyć jako prywatny, ale jest również widoczny dla podklas klasy zewnętrznej.

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

W istocie jedynym sposobem osiągnięcia tego, czego pragniesz, jest użycie klasy zewnętrznej jako formy przestrzeni nazw i ograniczenie wewnątrz tej klasy.

ShuggyCoUk
źródło
@ShuggyCoUK: public class Sub: Outer powinien być zapieczętowany public class Sub: Outer ??? Jednak +1 ... to działa dla mnie
IAbstract
0

Jeśli masz pojedynczy zestaw, możesz zdefiniować dowolną liczbę przestrzeni nazw w tym zestawie, ale bez względu na to, jaki modyfikator zastosujesz w środowisku IDE, zawsze będziesz w stanie zobaczyć klasy w innych przestrzeniach nazw.

Nathan
źródło
0

Nie jestem pewien, czy jest to bezpośrednio możliwe, ale kilka dobrych sposobów na udawanie to:

1) Niech klasy, które potrzebują tego rodzaju rzeczy, dziedziczą z pojedynczej klasy, która ma klasę pomocniczą jako klasę wewnętrzną.

2) Użyj metod rozszerzających, a następnie odwołuj się tylko do metod rozszerzających w przestrzeni nazw.

Wyatt Barnett
źródło