2026
struct a class: perché?Immaginiamo di rappresentare un orario:
// Approccio "naive": variabili separate
int ora = 14;
int minuto = 30;
int secondo = 0;
// Nessun controllo: questo è "valido"?
ora = 99;
minuto = -5;Problema: chiunque può assegnare valori non validi. Non c'è un controllo dei valori e delle operazioni permesse sui dati.
Una classe raggruppa dati (campi) e comportamenti (metodi) in un'unica entità:
| Modificatore | Visibilità |
|---|---|
public |
Chiunque può accedere |
private |
Solo codice interno alla classe |
protected |
Classe + classi derivate |
Regola pratica: campi → private, metodi/costruttori → public
https://learn.microsoft.com/en-us/dotnet/csharp/fundamentals/coding-style/identifier-names
Punti principali che ci interessano:
uso di PascalCase per nomi di classi e nomi di metodi (iniziale maiuscola e iniziali delle parole che compongono il nome anch'esse maiuscole)
esempio: AutoSportiva
campi privati devono iniziare con un underscore '_'
class Orario
{
private int _ora;
private int _minuto;
private int _secondo;
public void ImpostaOrario(int h, int m, int s)
{
_ora = (h >= 0 && h < 24) ? h : 0;
_minuto = (m >= 0 && m < 60) ? m : 0;
_secondo = (s >= 0 && s < 60) ? s : 0;
}
public void StampaOrario()
{
Console.WriteLine($"{_ora:D2}:{_minuto:D2}:{_secondo:D2}");
}
}// Creare un oggetto con "new"
Orario pranzo = new Orario();
// Chiamare i metodi
pranzo.ImpostaOrario(13, 0, 0);
pranzo.StampaOrario(); // → 13:00:00
// Tentativo di accesso diretto ai campi: ERRORE di compilazione
// pranzo._ora = 99; // 'Orario._ora' non e' accessibilenew alloca l'oggetto nella memoria heap
e restituisce un riferimento ad esso.
newclass Orario
{
private int _ora;
private int _minuto;
private int _secondo;
// Costruttore
public Orario(int ora, int minuto, int secondo)
{
_ora = (ora >= 0 && ora < 24) ? ora : 0;
_minuto = (minuto >= 0 && minuto < 60) ? minuto : 0;
_secondo = (secondo >= 0 && secondo < 60) ? secondo : 0;
}
public void Stampa()
{
Console.WriteLine($"{_ora:D2}:{_minuto:D2}:{_secondo:D2}");
}
}class Orario
{
private int _ora, _minuto, _secondo;
// Costruttore completo
public Orario(int ora, int minuto, int secondo)
{
ImpostaOrario(ora, minuto, secondo);
}
// Costruttore con soli ore e minuti
public Orario(int ora, int minuto)
: this(ora, minuto, 0) { } // chiama il costruttore sopra
// Costruttore predefinito (mezzanotte)
public Orario()
: this(0, 0, 0) { }
private void ImpostaOrario(int h, int m, int s)
{
if (h >= 0 && h < 24) {
_ora = h;
} else {
ora = 0;
}
if ( m >= 0 && m < 60) {
_minuto = m;
} else {
_minuto = 0;
}
if (s >= 0 && s < 60) {
_secondo = s;
} else {
_secondo = 0;
}
}
}Orario mezzanotte = new Orario(); // 00:00:00
Orario lezione = new Orario(8, 15); // 08:15:00
Orario fine = new Orario(10, 0, 0); // 10:00:00In C# non esiste il distruttore nel senso di C++. Il Garbage Collector libera automaticamente la memoria quando l'oggetto non è più raggiungibile.
C# introduce le properties: sintassi più pulita per i metodi che permettono di ottenere il valore di un attributo privato (getter) e per i metodi che permettono di impostare un valore per l'attributo (setter) https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/properties
class Orario
{
private int _ora; // attributo privato (
public int Ora
{
get { return _ora; }
set
{
if (value >= 0 && value < 24)
_ora = value;
}
}
}
// Utilizzo: sembra un campo, ma esegue il codice get/set
Orario t = new Orario();
t.Ora = 14; // chiama il setter
Console.WriteLine(t.Ora); // chiama il getterQuando non serve logica di validazione, si usa la forma breve:
class Studente
{
// Auto-property: il campo privato è generato automaticamente
public string Nome { get; set; }
public string Cognome { get; set; }
public int Eta { get; set; }
public Studente(string nome, string cognome, int eta)
{
Nome = nome;
Cognome = cognome;
Eta = eta;
}
public override string ToString()
{
return $"{Cognome} {Nome}, {Eta} anni";
}
}class Cerchio
{
public double Raggio { get; } // solo get → immutabile dopo costruzione
public Cerchio(double raggio)
{
Raggio = raggio;
}
// Proprietà calcolata (non memorizzata)
public double Area
{
get { return Math.PI * Raggio * Raggio; }
}
}
Cerchio c = new Cerchio(5.0);
Console.WriteLine(c.Area); // 78.53...
// c.Raggio = 10; // ERRORE: proprietà in sola letturaclass ContoBancario
{
private decimal _saldo;
public string Intestatario { get; }
public string IBAN { get; }
public decimal Saldo
{
get { return _saldo; }
}
public ContoBancario(string intestatario, string iban,
decimal saldoIniziale = 0)
{
Intestatario = intestatario;
IBAN = iban;
_saldo = saldoIniziale >= 0 ? saldoIniziale : 0;
} public bool Deposita(decimal importo)
{
if (importo <= 0) return false;
_saldo += importo;
return true;
}
public bool Preleva(decimal importo)
{
if (importo <= 0 || importo > _saldo) return false;
_saldo -= importo;
return true;
}
public override string ToString()
{
return $"{Intestatario} | {IBAN} | Saldo: {_saldo}";
}
}Questo codice può essere inserito come top-level statement PRIMA della dichiarazione della classe, oppure racchiuso in una funzione Main()
ContoBancario conto = new ContoBancario("Mario Rossi", "IT60X0542811101000000123456", 500);
conto.Deposita(200);
Console.WriteLine(conto); // Mario Rossi | ... | Saldo: €700,00
bool ok = conto.Preleva(1000);
Console.WriteLine(ok);
Console.WriteLine(conto.Saldo);
// conto._saldo = 99999; // ERRORE: campo privatoclass ContoBancario {
// resto della implementazione
public static void Main() {
ContoBancario conto = new ContoBancario("Mario Rossi", "IT60X0542811101000000123456", 500);
conto.Deposita(200);
Console.WriteLine(conto); // Mario Rossi | ... | Saldo: €700,00
bool ok = conto.Preleva(1000);
Console.WriteLine(ok);
Console.WriteLine(conto.Saldo);
// conto._saldo = 99999; // ERRORE: campo privato
}
}| Concetto | C# |
|---|---|
| Definizione classe | class NomeClasse { ... } |
| Creazione oggetto | NomeClasse obj = new NomeClasse(); |
| Campo privato | private tipo _nomeCampo; |
| Costruttore | public NomeClasse(params) { ... } |
| Proprietà | public tipo Nome { get; set; } |
| Metodo | public tipoRet NomeMetodo() { ... } |
| Memoria | Gestita dal Garbage Collector |
class B : A)virtual e overrideDictionary<K,V>"Make it work, make it right, make it fast." — Kent Beck