1. I principali modificatori di accesso in C#
Quando scrivi un programma, spesso vuoi controllare in modo preciso chi e da dove può vedere o modificare le tue variabili e chiamare i metodi. È un po' come in un condominio: non tutte le stanze sono aperte a tutti. Alcune sono accessibili solo ai residenti, altre solo ai tecnici.
In programmazione questo "controllo degli accessi" si risolve tramite i modificatori di accesso. Decidono se un membro della classe (variabile, campo, metodo, proprietà ecc.) è visibile fuori dalla classe, in un'altra classe, in un altro progetto. Questa è una delle principali realizzazioni dell'incapsulamento nell'OOP: nascondiamo i dettagli dell'implementazione, offrendo solo le "interfacce" necessarie verso l'esterno.
Ecco una tabella con i modificatori principali e una breve descrizione:
| Modificatore | Dove è visibile? (spiegato semplice) |
|---|---|
|
Ovunque (nel progetto e anche fuori — se c'è l'assembly) |
|
Solo dentro la stessa classe |
|
Uguale a private |
Sembra complicato? In realtà è tutto molto semplice. Vediamo con degli esempi dove conviene usare cosa.
2. Modificatore public — accesso libero per tutti
Il modificatore public rende la tua variabile o metodo visibile ovunque. Se dichiari un membro della classe come public, puoi accedervi da qualsiasi altro codice che vede la tua classe.
public class Person
{
public string Name;
public void SayHello()
{
Console.WriteLine($"Ciao! Mi chiamo {Name}");
}
}
Ora ovunque (nello stesso progetto o anche in altri, se aggiungi il riferimento all'assembly), puoi scrivere:
Person p = new Person();
p.Name = "Alisa";
p.SayHello();
Consiglio pratico: non rendere tutto public: è fondamentale per la sicurezza del codice.
3. Modificatore private — roba privata!
Il modificatore private chiude l'accesso al contenuto della classe: nessuno da fuori può vedere o modificare i dati. Di default tutti i campi e i metodi delle classi in C# sono private, se non specifichi altro.
public class Cup
{
private double volume; // Questo campo lo vede solo la classe Cup
public void Fill(double value)
{
volume = value; // Puoi usarlo dentro la classe
}
public double GetVolume()
{
return volume; // Ma da fuori nessuno sa che esiste volume
}
}
Qui volume è nascosto a tutti gli altri, ma può essere usato da qualsiasi metodo dentro Cup. Per sapere il volume, offriamo il metodo pubblico GetVolume().
4. Ambito di visibilità: variabili, metodi e classi
Ambito di visibilità — è la zona del programma dove il tuo nome (variabile, metodo, classe) ha senso ed è accessibile.
- Variabili locali (dichiarate dentro un metodo o un blocco di codice): visibili solo lì dentro.
- Parametri dei metodi: visibili solo dentro il metodo.
- Campi della classe: visibili ovunque nella classe (a seconda del modificatore di accesso).
- Classi: una classe annidata è visibile solo nella classe wrapper se è private, ecc.
Vediamo un esempio con l'ambito di visibilità:
public class Counter
{
private int count = 0; // visibile ovunque nella classe
public void Increment()
{
count++; // possiamo usare il campo
int temp = count * 2; // temp è visibile solo dentro Increment
}
public int GetCount()
{
// temp qui non è visibile!
return count;
}
}
Se provi ad accedere a temp dentro GetCount() — otterrai un errore.
5. Shadowing delle variabili
Shadowing — è quando in uno stesso ambito dichiari una variabile (o parametro) con lo stesso nome di una variabile in un ambito esterno. Dentro quel blocco il “nuovo” nome oscura quello vecchio, e non puoi più accedere direttamente al valore esterno.
Esempio di shadowing:
class ShadowDemo
{
int value = 10; // campo della classe
void PrintValue()
{
Console.WriteLine(value); // 10 — campo della classe
int value = 5; // variabile locale oscura il campo della classe
Console.WriteLine(value); // stampa 5, non 10
}
}
In questo esempio, quando scriviamo int value = 5;, questo oscura il campo della classe con lo stesso nome dentro il metodo. Quando accedi a value dentro PrintValue(), verrà usata la variabile locale, non il campo della classe.
Se proprio vuoi accedere al campo della classe, usa la parola chiave this:
class ShadowDemo
{
int value = 10;
void PrintValue()
{
Console.WriteLine(value); // 10 — campo della classe
int value = 5;
Console.WriteLine(value); // 5 — variabile locale
Console.WriteLine(this.value); // 10 — campo della classe
}
}
Lo shadowing può confondere, quindi è meglio dare nomi chiari e diversi alle variabili — soprattutto se lavori in team grandi.
GO TO FULL VERSION