it-swarm.it

In C #, qual è la differenza tra pubblico, privato, protetto e privo di modificatore di accesso?

In tutti gli anni del college ho usato public e vorrei conoscere la differenza tra public, private e protected?

Inoltre, cosa fa static anziché avere nulla?

678
MrM

Modificatori di accesso

Da docs.Microsoft.com

public

È possibile accedere al tipo o al membro tramite qualsiasi altro codice nello stesso assieme o in un altro assieme che fa riferimento a esso.

private

È possibile accedere al tipo o al membro solo tramite codice nella stessa classe o struttura.

protected

È possibile accedere al tipo o al membro solo tramite codice nella stessa classe o struttura o in una classe derivata.

private protected (aggiunto in C # 7.2)

È possibile accedere al tipo o al membro solo tramite codice nella stessa classe o struttura, o in una classe derivata dallo stesso assieme, ma non da un altro assieme.

internal

È possibile accedere al tipo o al membro tramite qualsiasi codice nello stesso assieme, ma non da un altro assieme.

protected internal

È possibile accedere al tipo o al membro tramite qualsiasi codice nello stesso assieme o da qualsiasi classe derivata in un altro assieme.

Quando nessun modificatore di accesso è impostato, viene utilizzato un modificatore di accesso predefinito. Quindi c'è sempre qualche forma di modificatore di accesso anche se non è impostato.

Statico

Il modificatore statico su una classe indica che la classe non può essere istanziata e che tutti i suoi membri sono statici. Un membro statico ha una versione indipendentemente dal numero di istanze del suo tipo di chiusura.

Una classe statica è fondamentalmente la stessa di una classe non statica, ma c'è una differenza: una classe statica non può essere istanziata esternamente. In altre parole, non è possibile utilizzare la nuova parola chiave per creare una variabile del tipo di classe. Poiché non esiste una variabile di istanza, puoi accedere ai membri di una classe statica utilizzando il nome della classe stessa.

Tuttavia, esiste una cosa come costruttore statico . Qualsiasi classe può avere una di queste, incluse le classi statiche. Non possono essere chiamati direttamente e non possono avere parametri (diversi da qualsiasi parametro di tipo sulla classe stessa). Un costruttore statico viene chiamato automaticamente per inizializzare la classe prima che venga creata la prima istanza o qualsiasi riferimento a membri statici. Somiglia a questo:

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

    public static string Bar { get; set; }
}

Le classi statiche sono spesso utilizzate come servizi, è possibile utilizzarle in questo modo:

MyStaticClass.ServiceMethod(...);
951
mbillard

Pubblico - Se riesci a vedere la classe, puoi vedere il metodo

Privato - Se sei parte di la classe, allora puoi vedere il metodo, altrimenti no.

Protetto - Uguale a Privato, più tutto discendenti può anche vedere il metodo.

Statico (classe) - Ricorda la distinzione tra "Classe" e "Oggetto"? Dimentica tutto questo. Sono uguali a "statici" ... la classe è l'istanza one-and-only di se stessa.

Static (metodo) - Ogni volta che si utilizza questo metodo, avrà un frame di riferimento indipendente dall'istanza effettiva della classe di cui fa parte.

154
JosephStyons

Una panoramica grafica (riassunto in poche parole)

Visibility

Per i valori di default se non hai inserito nessun modificatore di accesso di fronte, vedi qui:
Visibilità predefinita per classi e membri C # (campi, metodi, ecc.)?

Non nidificati

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

Nidificato:

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

Riguardo alla domanda di Nulla

  • I tipi di spazio dei nomi sono interni per impostazione predefinita
  • Per impostazione predefinita, qualsiasi membro del tipo, compresi i tipi nidificati, è privato
22
leppie

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();
        }
    }
}
19
Narottam Goyal

Ripubblicare i fantastici diagrammi da questa risposta .

Qui ci sono tutti i modificatori di accesso nei diagrammi di Venn, da più limitanti a più promiscui:

private:
enter image description here

private protected: - aggiunto in 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

15
Paul

Hmm.

Vedi qui: Modificatori di accesso .

In poche parole:

Pubblico fornisce il metodo o il tipo di visibilità completa da altri tipi/classi.

Privato consente solo il tipo che contiene il metodo privato/accesso variabile al metodo/variabile privato (si noti che le classi nidificate hanno anche accesso ai metodi/variabili private delle classi contenenti).

Protetto è simile al privato, ma le classi derivate possono anche accedere a metodi protetti.

"Niente" è equivalente a VB.NET. Anche se ti stai riferendo a "nulla" che significa "nessun modificatore di accesso", allora dipende, anche se una regola empirica molto approssimativa (certamente in C #) è che se non specifichi esplicitamente un modificatore di accesso, il metodo/variabile la dichiarazione è solitamente come restricted come può essere. cioè.

public class MyClass
{
    string s = "";
}

è effettivamente lo stesso di:

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

L'articolo MSDN collegato offrirà una descrizione completa quando non è specificato alcun modificatore di accesso.

11
CraigTP

public - può essere accessibile da chiunque ovunque.
private - è accessibile solo da con nella classe di cui fa parte.
protected - è accessibile solo dalla classe o da qualsiasi oggetto ereditato dalla classe.

Nulla è uguale a null ma in VB.
Statico significa che hai un'istanza di quell'oggetto, metodo per ogni istanza di quella classe.

8
Tony

Ancora un altro approccio visivo dell'attuale modificatore di access (C # 7.2). Speriamo che lo schema aiuti a ricordarlo più facilmente
(fare clic sull'immagine per la vista interattiva).

interactive access modifiers svg

Fuori dentro

Se ti sforzi di ricordare i modificatori di accesso in due parole, ricordaoutside-inside.

  • private protected : private outside (lo stesso assembly) protected inside (same Assembly)
  • protected internal : protected outside (lo stesso assembly) internal inside (same Assembly)
4
user1810087

Uno stato di Privato indica che le variabili possono essere accessibili solo da oggetti della stessa classe. Lo stato protetto estende tale accesso per includere anche i discendenti della classe.

"dal tavolo di cui sopra possiamo vedere la deferenza tra privato e protetto ... penso che entrambi siano uguali .... quindi quale sia la necessità di questo due comandi separati"

Controlla MSDN link per maggiori informazioni

4
Grant Hood

mmm ...

Statico significa che è possibile accedere a quella funzione senza avere un'istanza della classe.

È possibile accedere direttamente dalla definizione della classe.

4
gbianchi

Osserva attentamente la tua accessibilità alle tue lezioni. Classi e metodi pubblici e protetti sono di default accessibili a tutti.

Inoltre, Microsoft non è molto esplicita nel mostrare i modificatori di accesso (parole chiave pubbliche, protette, ecc.) Quando vengono create nuove classi in Visual Studio. Quindi, prenditi cura e pensa alla tua accessibilità della tua classe perché è la porta per i tuoi interni di implementazione.

3
Patrick Peters

Questi modificatori di accesso specificano dove sono visibili i tuoi membri. Probabilmente dovresti leggerlo. Prendi il collegamento dato da IainMH come punto di partenza.

I membri statici sono uno per classe e non uno per istanza.

3
jpfollenius

Penso che sia legato al buon OOP design. Se sei uno sviluppatore di una biblioteca, vuoi nascondere il funzionamento interno della tua biblioteca. In questo modo, puoi modificare i tuoi meccanismi interni della libreria in un secondo momento. Quindi metti i tuoi membri e metodi helper come privati, e solo i metodi di interfaccia sono pubblici. I metodi che dovrebbero essere sovrascritti dovrebbero essere protetti.

2

C # ha in totale 6 modificatori di accesso:

private : Il membro dichiarato con questa accessibilità può essere visibile all'interno del tipo di contenuto, non è visibile a nessun tipo derivato, altri tipi nello stesso Assembly o tipi al di fuori dell'Assembly contenente. vale a dire, l'accesso è limitato al solo tipo contenente.

protected : il membro dichiarato con questa accessibilità può essere visibile all'interno dei tipi derivati ​​dal tipo di contenuto all'interno dell'assembly contenente e i tipi derivati ​​dal tipo di contenuto all'esterno dell'assembly contenente. vale a dire, l'accesso è limitato ai tipi derivati ​​del tipo contenente.

internal : Il membro dichiarato con questa accessibilità può essere visibile all'interno dell'Assembly contenente questo membro, non è visibile a nessun assembly al di fuori dell'assembly contenente. ad esempio, l'accesso è limitato al solo contenimento di Assembly.

internal protected : Il membro dichiarato con questa accessibilità può essere visibile all'interno dei tipi derivati ​​dal tipo di contenuto all'interno o all'esterno dell'Assembly contenente, è anche visibile a qualsiasi tipo all'interno dell'Assembly contenente. vale a dire, l'accesso è limitato al contenimento di Assemblaggio o tipi derivati.

public : Il membro dichiarato con questa accessibilità può essere visibile all'interno dell'Assembly contenente questo membro o qualsiasi altro assembly che fa riferimento all'assembly contenente. vale a dire, l'accesso non è limitato.

C # 7.2 sta aggiungendo un nuovo livello di accessibilità:

private protected : il membro dichiarato con questa accessibilità può essere visibile all'interno dei tipi derivati ​​da questo tipo di contenuto all'interno dell'assembly contenente. Non è visibile a nessun tipo non derivato dal tipo di contenuto o al di fuori dell'Assembly contenente. vale a dire, l'accesso è limitato ai tipi derivati ​​all'interno dell'assembly contenente.

Sorgente che include un codice di esempio del nuovo modificatore di accesso protetto privato

1
Baccata