web-dev-qa-db-fra.com

En C #, quelle est la différence entre public, privé, protégé et ne pas avoir de modificateur d'accès?

Toutes mes années de collège, j’utilise public et voudrais connaître la différence entre public, private et protected?

Aussi que fait static par opposition à ne rien avoir?

691
MrM

Modificateurs d'accès

De docs.Microsoft.com

public

Le type ou le membre est accessible par tout autre code du même assemblage ou d'un autre assemblage qui le référence.

privé

Le type ou le membre n'est accessible que par code dans la même classe ou structure.

protected

Le type ou le membre n'est accessible que par code dans la même classe ou structure, ou dans une classe dérivée.

privé protégé (ajouté en C # 7.2)

Le type ou le membre n'est accessible que par code de la même classe ou structure, ou d'une classe dérivée du même assembly, mais pas d'un autre assembly.

interne

Le type ou le membre peut être accédé par n'importe quel code de la même assemblée, mais pas par une autre assemblée.

protégé en interne

Le type ou le membre peut être accédé par n'importe quel code du même assembly ou par n'importe quelle classe dérivée d'un autre assembly.

Lorsque aucun modificateur d'accès n'est défini, un modificateur d'accès par défaut est utilisé. Donc, il y a toujours une forme de modificateur d'accès même s'il n'est pas défini.

Statique

Le modificateur statique sur une classe signifie que la classe ne peut pas être instanciée et que tous ses membres sont statiques. Un membre statique a une version, quel que soit le nombre d'instances de son type englobant créées.

Une classe statique est fondamentalement la même chose qu'une classe non statique, mais il y a une différence: une classe statique ne peut pas être instanciée de manière externe. En d'autres termes, vous ne pouvez pas utiliser le nouveau mot-clé pour créer une variable du type de classe. Comme il n'y a pas de variable d'instance, vous accédez aux membres d'une classe statique en utilisant le nom de la classe lui-même.

Cependant, il existe une chose telle que constructeur statique . Toute classe peut en avoir une, y compris les classes statiques. Ils ne peuvent pas être appelés directement et ne peuvent pas avoir de paramètres (autres que les paramètres de type de la classe elle-même). Un constructeur statique est appelé automatiquement pour initialiser la classe avant la création de la première instance ou la référence des membres statiques. Ressemble à ça:

static class Foo()
{
    static Foo()
    {
        Bar = "fubar";
    }

    public static string Bar { get; set; }
}

Les classes statiques sont souvent utilisées en tant que services, vous pouvez les utiliser comme suit:

MyStaticClass.ServiceMethod(...);
968
mbillard

Public - Si vous pouvez voir la classe, alors vous pouvez voir la méthode

Privé - Si vous faites partie de la classe, vous pouvez voir la méthode, sinon vous ne le verrez pas.

Protected - Identique à Private, plus tous les descendants peuvent également voir la méthode.

Static (class) - Vous vous souvenez de la distinction entre "Classe" et "Objet"? Oublie tout ça. Ils sont identiques avec "statique" ... la classe est l'instance unique en elle-même.

Static (method) - Chaque fois que vous utilisez cette méthode, elle dispose d'un cadre de référence indépendant de l'instance réelle de la classe dont elle fait partie.

156
JosephStyons

Un aperçu graphique (résumé en quelques mots)

Visibility

Pour les valeurs par défaut si vous ne mettez pas de modificateur d'accès au début, voir ici:
Visibilité par défaut pour les classes et les membres C # (champs, méthodes, etc.)?

Non imbriqué

enum                              public
non-nested classes / structs      internal
interfaces                        internal
delegates in namespace            internal
class/struct member(s)            private
delegates nested in class/struct  private

Imbriqué:

nested enum      public
nested interface public
nested class     private
nested struct    private
147
Stefan Steiger

enter image description here

using System;

namespace ClassLibrary1
{
    public class SameAssemblyBaseClass
    {
        public string publicVariable = "public";
        protected string protectedVariable = "protected";
        protected internal string protected_InternalVariable = "protected internal";
        internal string internalVariable = "internal";
        private string privateVariable = "private";
        public void test()
        {
            // OK
            Console.WriteLine(privateVariable);

            // OK
            Console.WriteLine(publicVariable);

            // OK
            Console.WriteLine(protectedVariable);

            // OK
            Console.WriteLine(internalVariable);

            // OK
            Console.WriteLine(protected_InternalVariable);
        }
    }

    public class SameAssemblyDerivedClass : SameAssemblyBaseClass
    {
        public void test()
        {
            SameAssemblyDerivedClass p = new SameAssemblyDerivedClass();

            // NOT OK
            // Console.WriteLine(privateVariable);

            // OK
            Console.WriteLine(p.publicVariable);

            // OK
            Console.WriteLine(p.protectedVariable);

            // OK
            Console.WriteLine(p.internalVariable);

            // OK
            Console.WriteLine(p.protected_InternalVariable);
        }
    }

    public class SameAssemblyDifferentClass
    {
        public SameAssemblyDifferentClass()
        {
            SameAssemblyBaseClass p = new SameAssemblyBaseClass();

            // OK
            Console.WriteLine(p.publicVariable);

            // OK
            Console.WriteLine(p.internalVariable);

            // NOT OK
            // Console.WriteLine(privateVariable);

            // Error : 'ClassLibrary1.SameAssemblyBaseClass.protectedVariable' is inaccessible due to its protection level
            //Console.WriteLine(p.protectedVariable);

            // OK
            Console.WriteLine(p.protected_InternalVariable);
        }
    }
}

 using System;
        using ClassLibrary1;
        namespace ConsoleApplication4

{
    class DifferentAssemblyClass
    {
        public DifferentAssemblyClass()
        {
            SameAssemblyBaseClass p = new SameAssemblyBaseClass();

            // NOT OK
            // Console.WriteLine(p.privateVariable);

            // NOT OK
            // Console.WriteLine(p.internalVariable);

            // OK
            Console.WriteLine(p.publicVariable);

            // Error : 'ClassLibrary1.SameAssemblyBaseClass.protectedVariable' is inaccessible due to its protection level
            // Console.WriteLine(p.protectedVariable);

            // Error : 'ClassLibrary1.SameAssemblyBaseClass.protected_InternalVariable' is inaccessible due to its protection level
            // Console.WriteLine(p.protected_InternalVariable);
        }
    }

    class DifferentAssemblyDerivedClass : SameAssemblyBaseClass
    {
        static void Main(string[] args)
        {
            DifferentAssemblyDerivedClass p = new DifferentAssemblyDerivedClass();

            // NOT OK
            // Console.WriteLine(p.privateVariable);

            // NOT OK
            //Console.WriteLine(p.internalVariable);

            // OK
            Console.WriteLine(p.publicVariable);

            // OK
            Console.WriteLine(p.protectedVariable);

            // OK
            Console.WriteLine(p.protected_InternalVariable);

            SameAssemblyDerivedClass dd = new SameAssemblyDerivedClass();
            dd.test();
        }
    }
}
22
Narottam Goyal

En ce qui concerne la question de rien

  • Les types d'espace de noms sont internes par défaut
  • Tout membre de type, y compris les types imbriqués, est privé par défaut
22
leppie

Republier les superbes diagrammes de cette réponse .

Voici tous les modificateurs d'accès dans les diagrammes de Venn, du plus restrictif au plus promiscuité:

private:
enter image description here

private protected: - ajouté en C # 7.2
enter image description here

internal:
enter image description here

protected:
enter image description here

protected internal:
enter image description here

public:
enter image description here

19
Paul

Hmm.

Voir ici: Modificateurs d'accès .

En un mot:

Public donne à la méthode ou au type une visibilité complète à partir d'autres types/classes.

Private n'autorise que le type contenant la méthode privée/variable accès à la méthode privée/variable (notez que les classes imbriquées ont également accès aux classes contenant méthodes privées/variables).

Protected est similaire à private, sauf que les classes dérivées peuvent également accéder à des méthodes protégées.

"Nothing" est l'équivalent de null pour VB.NET. Bien que si vous vous référez à "rien" signifiant "pas de modificateur d'accès", cela dépend, bien qu'une règle très approximative (certainement en C #) est que si vous ne spécifiez pas explicitement un modificateur d'accès, la méthode/variable la déclaration est généralement aussi restreinte que possible . c'est à dire.

public class MyClass
{
    string s = "";
}

est effectivement la même chose que:

public class MyClass
{
    private string s = "";
}

L'article MSDN lié offrira une description complète lorsqu'il n'y a pas de modificateur d'accès explicitement spécifié.

11
CraigTP

public - peut être accessible par n'importe qui n'importe où.
private - est accessible uniquement depuis la classe dont il fait partie.
protected - est accessible uniquement depuis avec dans la classe ou tout objet héritant de la classe.

Rien n'est comme nul mais en VB.
Statique signifie que vous avez une instance de cet objet, méthode pour chaque instance de cette classe.

8
Tony

Encore une autre approche visuelle du courant modificateur d'accès (C # 7.2). Espérons que le schéma aide à s'en souvenir plus facilement
(cliquez sur l'image pour une vue interactive.)

interactive access modifiers svg

Extérieur intérieur

Si vous avez du mal à vous souvenir des modificateurs d'accès à deux mots, rappelez-vous outside-inside .

  • privé protégé : privé extérieur (le même assemblage) protégé à l'intérieur de (même assemblage)
  • protégé interne : protégé extérieur (le même assemblage) interne à l'intérieur (même assemblage)
6
user1810087

Un statut de privé indique que les variables ne sont accessibles qu'aux objets de la même classe. Le statut protégé étend cet accès pour inclure également les descendants de la classe.

"à partir du tableau ci-dessus, nous pouvons voir la déférence entre privé et protégé ... je pense que les deux sont identiques .... alors quel est le besoin de ces deux commandes séparées"

Vérifiez le lien MSDN pour plus d'informations.

4
Grant Hood

mmm ...

Statique signifie que vous pouvez accéder à cette fonction sans avoir d'instance de la classe.

Vous pouvez accéder directement à partir de la définition de la classe.

4
gbianchi

Surveillez attentivement l'accessibilité de vos cours. Les classes et méthodes publiques et protégées sont par défaut accessibles à tous.

De plus, Microsoft n’explique pas très clairement la présentation de modificateurs d’accès (mots clés publics, protégés, etc.) lors de la création de nouvelles classes dans Visual Studio. Alors, prenez bien soin de votre accessibilité à votre classe et réfléchissez-y, car c’est la porte de votre implémentation interne.

3
Patrick Peters

Ces modificateurs d'accès spécifient où vos membres sont visibles. Vous devriez probablement lire ceci. Prenez le lien donné par IainMH comme point de départ.

Les membres statiques sont un par classe et non un par instance.

3
jpfollenius

Je pense que cela est lié au bon design OOP. Si vous développez une bibliothèque, vous souhaitez masquer le fonctionnement interne de votre bibliothèque. De cette façon, vous pourrez modifier le fonctionnement interne de votre bibliothèque ultérieurement. Vous mettez donc vos méthodes membres et d'assistance en tant que données privées et seules les méthodes d'interface sont publiques. Les méthodes qui doivent être écrasées doivent être protégées.

2
Darius Kucinskas

C # a au total 6 modificateurs d'accès:

private : le membre déclaré avec cette accessibilité peut être visible dans le type conteneur, il n'est visible par aucun type dérivé, aucun type appartenant au même ensemble ou types en dehors de l'assemblage contenant. c'est-à-dire que l'accès est limité au type contenant uniquement.

protected : le membre déclaré avec cette accessibilité peut être visible dans les types dérivés du type conteneur dans l'ensemble Assembly et les types dérivés du type conteneur en dehors de l'Assemblée contenante. c'est-à-dire que l'accès est limité aux types dérivés du type contenant.

internal : Le membre déclaré avec cette accessibilité peut être visible dans l'Assemblée contenant ce membre, il ne sera visible par aucune Assemblée en dehors de l'Assemblée contenant. c'est-à-dire que l'accès est limité à un ensemble uniquement.

internal protected : le membre déclaré avec cette accessibilité peut être visible dans les types dérivés du type conteneur à l'intérieur ou à l'extérieur de l'assembly conteneur, il est également visible. à tous les types dans l’Assemblée contenant. c'est-à-dire que l'accès est limité à contenir des types Assembly ou dérivés.

public : Le membre déclaré avec cette accessibilité peut être visible dans l'Assemblée contenant ce membre ou dans toute autre Assemblée faisant référence à l'Assemblée contenant. c'est-à-dire que l'accès n'est pas limité.

C # 7.2 ajoute un nouveau niveau d'accessibilité:

private protected : le membre déclaré avec cette accessibilité peut être visible dans les types dérivés de ce type contenant dans l'ensemble contenant. Il n'est visible par aucun type non dérivé du type conteneur ou extérieur à l'ensemble conteneur. c'est-à-dire que l'accès est limité aux types dérivés dans l'assembly contenant.

Source contenant un exemple de code du nouveau modificateur d'accès protégé privé

1
Baccata