Visibilité des classes d'espace de noms uniquement dans C # /. NET?

87

En C #, pouvez-vous rendre une classe visible uniquement dans son propre espace de noms sans vivre dans un assembly différent? Cela semble utile pour les classes d'assistance typiques qui ne devraient pas être utilisées ailleurs. (c'est-à-dire ce que Java appelle les classes privées de package)

nos
la source
Je ne comprends pas votre question. J'ai supprimé mes réponses parce que vous ne vouliez pas dire «interne»?
Zyphrax
3
@nos: recherchez-vous l'équivalent de la visibilité au niveau du package de Java?
John Saunders

Réponses:

35

Je ne pense pas que ce que tu veux soit possible.

Steven Sudit
la source
80

Vous pouvez créer les classes, internalmais cela empêche uniquement quiconque en dehors de l' assembly d'utiliser la classe. Mais vous devez toujours créer un assembly distinct pour chaque espace de noms avec lequel vous souhaitez effectuer cette opération. Je suppose que c'est pourquoi vous ne voudriez pas le faire.

Obtenir le compilateur C # pour appliquer la visibilité de l'espace de noms

Il y a un article ici ( visibilité de l'espace de noms en C # ) qui montre une méthode d'utilisation de classes partielles comme forme de «faux espace de noms» que vous pourriez trouver utile.

L'auteur souligne que cela ne fonctionne pas parfaitement et il discute des lacunes. Le principal problème est que les concepteurs C # ont conçu C # pour ne pas fonctionner de cette façon.Cela s'écarte fortement des pratiques de codage attendues en C # /. NET, qui est l'un des plus grands avantages de .NET Frameworks.

C'est un truc génial ... maintenant ne le faites pas .

Robert Cartaino
la source
1
Je viens de trouver un exemple:System.Net.Mime.MediaTypeNames.Application
Bitterblue
L'article dit que vous devez préfixer chaque appel avec votre nom "d'espace de noms", mais vous n'en avez pas besoin avec C # 6 "using static". Vous pouvez faire de l '«espace de noms» une classe partielle statique, puis dans le code du client écrire «en utilisant statique»
Pumkko
@Pumkko La classe n'a pas besoin d'être statique pour pouvoir utiliser l'instruction 'using static', bien que si vous l'utilisez comme espace de noms, elle devrait l'être quand même.
Fuzzy Logic
21

interne est la confidentialité de l'assemblage (module à proprement parler). Cela n'a aucun effet sur la visibilité de l'espace de noms.

La seule façon d'obtenir la confidentialité d'une classe à partir d'autres classes au sein du même assembly est qu'une classe soit une classe interne.

À ce stade, si la classe est privée, elle est invisible pour tout ce qui n'est pas dans cette classe ou la classe externe elle-même.

S'il est protégé, il est visible par tous ceux qui pourraient le voir lorsqu'il est privé, mais il est également visible par les sous-classes de la classe externe.

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

En substance, la seule façon d'atteindre ce que vous désirez est d'utiliser la classe externe comme une forme d'espace de noms et de la restreindre au sein de cette classe.

ShuggyCoUk
la source
@ShuggyCoUK: classe publique Sub: Outer doit être scellé classe publique Sub: Outer ??? +1 cependant ... ça marche pour moi
IAbstract
0

Si vous avez un seul assembly, vous pouvez définir autant d'espaces de noms dans cet assembly que vous le souhaitez, mais quel que soit le modificateur que vous appliquez dans l'EDI, vous pourrez toujours voir les classes dans d'autres espaces de noms.

Nathan
la source
0

Je ne sais pas si c'est directement possible, mais quelques bonnes façons de le simuler seraient:

1) Les classes qui ont besoin de ce genre de choses héritent d'une classe unique qui a la classe d'assistance comme classe interne.

2) Utilisez des méthodes d'extension, puis référencez uniquement les méthodes d'extension dans l'espace de noms.

Wyatt Barnett
la source