Quels sont les modificateurs d'accès par défaut en C #?

384

Quel est le modificateur d'accès par défaut pour les classes, méthodes, membres, constructeurs, délégués et interfaces?

Surya sasidhar
la source

Réponses:

486

L'accès par défaut pour tout en C # est "l'accès le plus restreint que vous puissiez déclarer pour ce membre" .

Ainsi, par exemple:

namespace MyCompany
{
    class Outer
    {
        void Foo() {}
        class Inner {}
    }
}

est équivalent à

namespace MyCompany
{
    internal class Outer
    {
        private void Foo() {}
        private class Inner {}
    }
}

La seule exception à cela consiste à restreindre une partie d'une propriété (généralement le setter) que l'accessibilité déclarée de la propriété elle-même:

public string Name
{
    get { ... }
    private set { ... } // This isn't the default, have to do it explicitly
}

Voici ce que la spécification C # 3.0 a à dire (section 3.5.1):

Selon le contexte dans lequel une déclaration de membre a lieu, seuls certains types d'accessibilité déclarée sont autorisés. En outre, lorsqu'une déclaration de membre ne comprend aucun modificateur d'accès, le contexte dans lequel la déclaration a lieu détermine l'accessibilité déclarée par défaut.

  • Les espaces de noms ont implicitement une accessibilité déclarée publique. Aucun modificateur d'accès n'est autorisé sur les déclarations d'espace de noms.
  • Les types déclarés dans les unités de compilation ou les espaces de noms peuvent avoir une accessibilité déclarée publique ou interne et par défaut une accessibilité déclarée interne.
  • Les membres de la classe peuvent avoir l'un des cinq types d'accessibilité déclarée et par défaut l'accessibilité déclarée privée. (Notez qu'un type déclaré en tant que membre d'une classe peut avoir l'un des cinq types d'accessibilité déclarée, tandis qu'un type déclaré en tant que membre d'un espace de noms ne peut avoir qu'une accessibilité déclarée publique ou interne.)
  • Les membres de structure peuvent avoir une accessibilité déclarée publique, interne ou privée et par défaut une accessibilité déclarée privée car les structures sont implicitement scellées. Les membres de structure introduits dans une structure (c'est-à-dire non hérités par cette structure) ne peuvent pas avoir d'accessibilité déclarée interne protégée ou protégée. (Notez qu'un type déclaré comme membre d'une structure peut avoir une accessibilité déclarée publique, interne ou privée, tandis qu'un type déclaré comme membre d'un espace de noms ne peut avoir qu'une accessibilité déclarée publique ou interne.)
  • Les membres de l'interface ont implicitement une accessibilité déclarée publique. Aucun modificateur d'accès n'est autorisé sur les déclarations de membre d'interface.
  • Les membres de l'énumération ont implicitement déclaré l'accessibilité publique. Aucun modificateur d'accès n'est autorisé sur les déclarations de membres d'énumération.

(Notez que les types imbriqués relèveraient des parties "membres de la classe" ou "membres de la structure" - et donc par défaut en visibilité privée.)

Jon Skeet
la source
154
top level class: internal
method: private
members (unless an interface or enum): private (including nested classes)
members (of interface or enum): public
constructor: private (note that if no constructor is explicitly defined, a public default constructor will be automatically defined)
delegate: internal
interface: internal
explicitly implemented interface member: public!
John Buchanan
la source
13
Cela ne montre pas clairement que si une classe est également membre (car elle est de type imbriqué), elle est par défaut privée. De plus, les membres d'une interface et d'une énumération sont toujours publics.
Jon Skeet
1
@niry Non, ce n'est pas privé. C'est public. Il n'obtient tout simplement pas un emplacement dans le type d'implémentation, donc si class Foo : IFoo { IFoo.M() {} } ... Foo a = new Foo();, vous ne pouvez pas y accéder Mavec a.M(), cependant vous pouvez y accéder avec (a as IFoo).M(). (Consultez les spécifications pour plus d'informations sur les détails)
M.Stramm
130

Réponse courte: accès minimum possible (cf. réponse de Jon Skeet).

Longue réponse:

Types non imbriqués , énumération et accessibilité des délégués ( ne peuvent avoir qu'une accessibilité interne ou publique )

                     | Default   | Permitted declared accessibilities
------------------------------------------------------------------
namespace            | public    | none (always implicitly public)

enum                 | public    | none (always implicitly public)

interface            | internal  | public, internal

class                | internal  | public, internal

struct               | internal  | public, internal

delegate             | internal  | public, internal

Type imbriqué et accessibilité des membres

                     | Default   | Permitted declared accessibilities
------------------------------------------------------------------
namespace            | public    | none (always implicitly public)

enum                 | public    | none (always implicitly public)

interface            | public    | none

class                | private   | All¹

struct               | private   | public, internal, private²

delegate             | private   | All¹

constructor          | private   | All¹

interface member     | public    | none (always implicitly public)

method               | private   | All¹

field                | private   | All¹

user-defined operator| none      | public (must be declared public)

¹ Tous === public, protégé, interne, privé, interne protégé

² Les structures ne peuvent pas hériter des structures ou des classes (bien qu'elles le puissent, des interfaces), donc protégé n'est pas un modificateur valide

L'accessibilité d'un type imbriqué dépend de son domaine d'accessibilité, qui est déterminé à la fois par l'accessibilité déclarée du membre et le domaine d'accessibilité du type contenant immédiatement. Cependant, le domaine d'accessibilité d'un type imbriqué ne peut pas dépasser celui du type conteneur.

Remarque: CIL a également la disposition pour protégé et interne (par opposition à l'existant protégé "ou" interne), mais à ma connaissance ce n'est pas actuellement disponible pour une utilisation en C #.


Voir:

http://msdn.microsoft.com/en-us/library/ba0a1yw2.aspx
http://msdn.microsoft.com/en-us/library/ms173121.aspx
http://msdn.microsoft.com/en- us / library / cx03xt0t.aspx
(Man I love Microsoft URIs ...)

Ben Aston
la source
12

Jetez un œil aux modificateurs d'accès (Guide de programmation C #)

Accessibilité des classes et des structures

Les classes et les structures qui sont déclarées directement dans un espace de noms (en d'autres termes, qui ne sont pas imbriquées dans d'autres classes ou structures) peuvent être publiques ou internes. Interne est la valeur par défaut si aucun modificateur d'accès n'est spécifié.

Les membres de structure, y compris les classes et les structures imbriquées, peuvent être déclarés publics, internes ou privés. Les membres de classe, y compris les classes et structures imbriquées, peuvent être publics, protégés internes, protégés, internes, privés protégés ou privés. Le niveau d'accès pour les membres de classe et les membres de structure, y compris les classes et structures imbriquées, est privé par défaut. Les types imbriqués privés ne sont pas accessibles depuis l'extérieur du type conteneur.

Les classes dérivées ne peuvent pas avoir une plus grande accessibilité que leurs types de base. En d'autres termes, vous ne pouvez pas avoir une classe publique B qui dérive d'une classe interne A. Si cela était autorisé, cela aurait pour effet de rendre A public, car tous les membres protégés ou internes de A sont accessibles à partir de la classe dérivée.

Vous pouvez activer d'autres assemblys spécifiques pour accéder à vos types internes en utilisant le InternalsVisibleToAttribute. Pour plus d'informations, voir Assemblages d'amis.

Accessibilité des membres de classe et de structure

Les membres de classe (y compris les classes et les structures imbriquées) peuvent être déclarés avec l'un des six types d'accès. Les membres de structure ne peuvent pas être déclarés protégés car les structures ne prennent pas en charge l'héritage.

Normalement, l'accessibilité d'un membre n'est pas supérieure à l'accessibilité du type qui le contient. Cependant, un membre public d'une classe interne peut être accessible de l'extérieur de l'assembly si le membre implémente des méthodes d'interface ou remplace des méthodes virtuelles définies dans une classe de base publique.

Le type de tout membre qui est un champ, une propriété ou un événement doit être au moins aussi accessible que le membre lui-même. De même, le type de retour et les types de paramètres de tout membre qui est une méthode, un indexeur ou un délégué doivent être au moins aussi accessibles que le membre lui-même. Par exemple, vous ne pouvez pas avoir de méthode publique M qui renvoie une classe C à moins que C ne soit également public. De même, vous ne pouvez pas avoir une propriété protégée de type A si A est déclaré privé.

Les opérateurs définis par l'utilisateur doivent toujours être déclarés publics et statiques. Pour plus d'informations, voir Surcharge d'opérateur.

Les finaliseurs ne peuvent pas avoir de modificateurs d'accessibilité.

Autres types

Les interfaces déclarées directement dans un espace de noms peuvent être déclarées publiques ou internes et, tout comme les classes et les structures, les interfaces utilisent par défaut un accès interne. Les membres de l'interface sont toujours publics car le but d'une interface est de permettre à d'autres types d'accéder à une classe ou une structure. Aucun modificateur d'accès ne peut être appliqué aux membres de l'interface.

Les membres d'énumération sont toujours publics et aucun modificateur d'accès ne peut être appliqué.

Les délégués se comportent comme des classes et des structures. Par défaut, ils ont un accès interne lorsqu'ils sont déclarés directement dans un espace de noms et un accès privé lorsqu'ils sont imbriqués.

Adriaan Stander
la source
8

La classe est interne par défaut.

  • Les membres de la classe sont privés par défaut.

L'interface est interne par défaut.

  • Les membres de l'interface sont publics par défaut. (Les interfaces ne nous permettent pas de spécifier tout type d'accessibilité à ses membres.)

    Remarque: Si vous essayez de spécifier un spécificateur d'accès aux membres de l'interface, il affiche une erreur de compilation.

La structure est interne par défaut.

  • Les membres de la structure sont privés par défaut.
Kamala Hanchinal
la source
5

Je voudrais ajouter un lien de documentation. Découvrez plus de détails ici .

entrez la description de l'image ici

Asif Mushtaq
la source
1
La classe est par défaut interne et non privée.
Baahubali
1
Où j'ai écrit le cours est privé?
Asif Mushtaq
Cette table n'est valide que pour les types imbriqués.
BlueSilver
La classe est interne par défaut et la classe à l'intérieur de l'espace de noms ne peut pas être privée. mais la classe à l'intérieur d'une classe (classe imbriquée) peut être privée
Arun
Le modificateur d'accès de l'interface est Interne par défaut.
Kamala Hanchinal
4

La réponse la plus simple est la suivante .....

Tous les membres en C # acceptent toujours le modificateur LE MOINS accessible par défaut.

C'est pourquoi toutes les classes de niveau supérieur d'un assembly sont "internes" par défaut, ce qui signifie qu'elles sont publiques à l'assembly dans lequel elles se trouvent, mais privées ou exclues de l'accès aux assemblys externes. La seule autre option pour une classe de niveau supérieur est public qui est plus accessible. Pour les types imbriqués, tout est privé à l'exception de quelques rares exceptions comme les membres d'énumérations et d'interfaces qui ne peuvent être que publics. Quelques exemples. Dans le cas des classes et interfaces de niveau supérieur, les valeurs par défaut sont:

classe Animal identique à la classe interne Animal

interface Animal identique à l'interface publique Animal

Dans le cas de classes et d'interfaces imbriquées (à l'intérieur de types), les valeurs par défaut sont:

classe Animal identique à la classe privée Animal

interface Animal identique à l'interface privée Animal

Si vous supposez simplement que la valeur par défaut est toujours la plus privée, vous n'avez pas besoin d'utiliser d'accesseurs jusqu'à ce que vous deviez modifier la valeur par défaut. Facile.

Stokely
la source
1

Interne est le modificateur par défaut

renjucool
la source
0

Niveau d'espace de noms: internal

Niveau de type: private

leppie
la source