LE PROPERTY IN C#
Le property in C# sono il meccanismo che ci mette a disposizione il linguaggio per realizzare l’incapsulamento dei dati. Abbiamo visto nel post precedente come sia possibile incapsulare una certa variabile definita all’interno di una classe, rendendola privata, e implementando due metodi pubblici che consentono rispettivamente di accedere dall’esterno in lettura e scrittura alla variabile stessa. Riporto il codice:
using System; namespace Property { public class Persona { private string nome; public string GetNome() { return this.nome; } public void SetNome(string nome) { //qui ci vanno eventuali controlli prima di assegnare l'attributo nome. this.nome=nome; } } class Program { static void Main(string[] args) { } } }
Questo modo di rendere privati gli attributi o variabili di istanza consente di nascondere all’esterno la gestione dell’attributo, infatti definendo due metodi pubblici che in gergo vengono chiamati Getter e Setter la variabile prima di presentarla all’esterno può nei metodi appena citati scrivere codice supplementare come ad esempio la validazione. Siccome queste sono operazioni frequenti il C# ci viene incontro con le property che rappresentano il meccanismo per realizzare l’incapsulamento. Vediamo come si dichiara e implementa una property.
using System; namespace Property { public class Persona { private string nome; public string Nome { get{ return this.nome; } set{ this.nome=value; } } } class Program { static void Main(string[] args) { } } }
Viene dichiarata una proprietà pubblica avente per convenzione lo stesso nome dell’attributo ma con l’iniziale maiuscola e aperto un blocco di codice in cui i metodi Getter e Setter sono sostituiti con le keyword get e set. Inoltre viene definita la parola chiave value che dietro le quinte accede al nuovo valore passato. Nei blocchi di codice get e set nulla ci vieta di scrivere codice supplementare.
PROPERTY IN C SHARP COME UTILIZZARLE
Dopo aver definito una property vediamo come essa viene usata dall’esterno. Ti riporto il codice
using System; namespace Property { public class Persona { private string nome; public string Nome { get{ return this.nome; } set{ this.nome=value; } } } class Program { static void Main(string[] args) { Persona p = new Persona(); p.Nome="Marco";/*--VIENE INVOCATO IL METODO SET DELLA PROPERTY E ALLA KEYWORD VALUE VIENE PASSATO IL VALORE "MARCO" NULLA CI VIETA DI ACCEDERE A VALUE E FARE TUTTI I CONTROLLI O MODIFICARNE IL VALORE.*/ Console.WriteLine(p.Nome);//VIENE INVOCATO IL GET DELLA PROPERTY. } } }
Come vedi prima si crea un’istanza della classe Persona poi si accede alla property Nome.
BACKING FIELD DI UNA PROPERTY IN C SHARP
Quando dichiariamo una property il backing field ossia la variabile privata private string nome non è obbligatorio dichiararla, inoltre le property hanno i modificatori di accesso, nell’esempio che ti ho fatto sopra la property è definita pubblica quindi get e set erediteranno tale modificatore, tuttavia possiamo cambiare il comportamento di default ad esempio implementando un set privato. Ciò significa che la proprietà sarà in sola lettura e quindi si può impostare solo all’interno della classe.
using System; namespace Property { public class Persona { private string nome; public string Nome { get{ return this.nome; } private set{ this.nome=value; } } } class Program { static void Main(string[] args) { } } }
AUTO IMPLEMENTED PROPERTY
Se non implementiamo codice nel get e nel set è possibile condensare ulteriormente una proprietà nel seguente modo:
using System; namespace Property { public class Persona { public string Nome {get;set;} } class Program { static void Main(string[] args) { Persona p = new Persona(); p.Nome="Mario"; string s = p.Nome; } } }
In tal caso sarà il compilatore a generare dietro le quinte il campo privato ossia il backing field e il resto del codice della property. È possibile specificare anche un valore di default nel seguente modo:
using System; namespace Property { public class Persona { public string Nome {get;set;}="Marco"; } class Program { static void Main(string[] args) { Persona p = new Persona(); p.Nome="Mario"; string s = p.Nome; } } }
OBJECT INITIALIZER
È possible inizializzare le property in un colpo solo con questa sintassi:
using System; namespace Property { public class Persona { public string Nome {get;set;} public String Cognome {get;set;} } class Program { static void Main(string[] args) { Persona p = new() {Nome="Mario",Cognome="Verdi"}; } } }
RIPRENDIAMO IL CODICE DI ESEMPIO PRECEDENTE E MODIFICHIAMOLO USANDO LE PROPERTY
using System; namespace EsercitazioneProperty { internal class Program { private static void Main(string[] args) { Utente utente1 = new(){Id="1234560", Nome="Mario", Cognome="Rossi", NumeroConto = "4356789"}; utente1.Saldo = 13000m; Utente utente2 = new(){Id="12345678",Nome = "Mario",Cognome = "Verdi",NumeroConto = "435679879"}; utente2.Saldo = 30000m; utente1.SaldoCorrente(); utente2.SaldoCorrente(); var b1 = new Banca("1234567890", "UBI Banca"); var b2 = new Banca("1234576543", "UBI Banca"); b1.Preleva(3000m,utente1); b2.Preleva(10000m,utente2); utente1.SaldoCorrente(); utente2.SaldoCorrente(); } } internal class Utente { private decimal saldo; public string Id { get; set; } public string Nome { get; set; } public string Cognome { get; set; } public decimal Saldo { get => saldo; set { if (value < 0) Console.WriteLine($"Impossibile impostare il saldo. Valore passato: {value}"); else saldo = value; } } public string NumeroConto { get; set; } public string Denominazione => "Utente " + Nome + " " + Cognome; internal void SaldoCorrente() { Console.WriteLine($"Utente {Nome + " " + Cognome} saldo corrente: {Saldo}"); } } internal class Banca { public Banca(string id, string denominazione, string abi, string cab) { Id = id; Denominazione = denominazione; Abi = abi; Cab = cab; } public Banca(string id, string denominazione) : this(id, denominazione, "06098", "14400") { } public string Id { get; set; } public string Denominazione { get; set; } public string Abi { get; set; } public string Cab { get; set; } public Utente Utente { get; set; } internal void Preleva(decimal importo, Utente utente) { Utente = utente; var saldo = Utente.Saldo; if (importo > saldo) { Console.WriteLine($"Operazione di prelievo non ammessa, importo richiesto {importo}"); return; } if (importo < 0) { Console.WriteLine($"Importo prelevato non valido: {importo}"); return; } Utente.Saldo -= importo; Utente = null; } internal void Accredito(decimal importo,Utente utente) { Utente = utente; if (importo < 0) { Console.WriteLine($"Importo accreditato non valido: {importo}"); return; } Utente.Saldo += importo; Utente = null; } } }
APPROFONDIMENTO
Le proprietà in C# sono un modo elegante per accedere ai campi privati di una classe. Permettono di controllare la lettura e la scrittura dei dati in modo sicuro e sono una parte fondamentale dell’incapsulamento nella programmazione orientata agli oggetti. Ecco una spiegazione semplice con un esempio:
Cos’è una proprietà?
Una proprietà in C# è un membro di una classe che fornisce un meccanismo flessibile per leggere, scrivere o calcolare il valore di un campo privato. Una proprietà può essere lettura-scrittura, sola lettura o sola scrittura.
Sintassi di base
Ecco un esempio di una classe con una proprietà:
public class Persona
{
// Campo privato
private string nome;
//Proprietà pubblica
public string Nome
{
get
{
return nome;
}
set
{
nome = value;
}
}
}
Spiegazione dell’esempio
1. Campo privato: private string nome;
• Questo è un campo privato della classe Persona. È privato, quindi può essere accessibile solo all’interno della classe stessa.
2. Proprietà pubblica: public string Nome { get; set; }
• get è un accessore che restituisce il valore del campo privato nome.
• set è un modificatore che imposta il valore del campo privato nome.
• Questa proprietà permette di leggere e scrivere il valore di nome dall’esterno della classe, ma tramite i metodi get e set.
Utilizzo della proprietà
Ecco come puoi usare questa proprietà:
public class Programma
{
public static void Main()
{
Persona persona = new Persona();
// Impostare il valore tramite la proprietà
persona.Nome = “Mario Rossi“;
// Ottenere il valore tramite la proprietà
string nome = persona.Nome;
Console.WriteLine(nome); // Output: Mario Rossi
}
}
Proprietà automatiche
C# supporta anche le proprietà automatiche, che semplificano ulteriormente la definizione delle proprietà senza dover dichiarare un campo privato separato:
public class Persona
{
public string Nome { get; set; }
}
Con le proprietà automatiche, il compilatore genera automaticamente un campo privato dietro le quinte. Questo è utile quando non hai bisogno di una logica aggiuntiva nei metodi get o set.
Proprietà di sola lettura e di sola scrittura
Puoi creare proprietà di sola lettura o di sola scrittura omettendo rispettivamente set o get:
public class Persona
{
private string nome;
private string cognome;
// Proprietà di sola lettura
public string Nome
{
get
{
return nome;
}
}
// Proprietà di sola scrittura
public string Cognome
{
set
{
cognome = value;
}
}
}
Conclusione
Le proprietà in C# sono potenti strumenti per gestire l’accesso ai dati di una classe, fornendo un modo sicuro e controllato per leggere e scrivere i valori dei campi privati. Spero che questa spiegazione ti sia stata utile per comprendere le basi delle proprietà in C#.
Lascia un commento