CodeGym /Corsi /C# SELF /Proprietà (Properties) in C#

Proprietà (Properties) in C#

C# SELF
Livello 17 , Lezione 1
Disponibile

1. Introduzione

Partiamo dai problemi che sorgono quando usi direttamente i campi. Se dichiari un campo come public, può essere modificato subito e direttamente da qualsiasi parte del programma:

public class Dog
{
    public string Name;
}

Dog dog = new Dog();
dog.Name = ""; // O_o ... è come "nome del cane = stringa vuota"!

L'utente può assegnare al campo Name dei valori completamente assurdi, anche quelli che non hanno senso per il tuo dominio: una stringa vuota, un nome troppo lungo, o addirittura null. È come se qualcuno stesse montando il tuo nuovo armadio IKEA e tu gli dessi accesso completo alla fabbrica di falegnameria.

Ricorda che incapsulamento significa che l'oggetto controlla i suoi dati da solo. Non lasciamo entrare chiunque nelle nostre cose interne, ma diamo delle "porticine" speciali — le proprietà (Properties), attraverso cui si accede al campo, ma con la possibilità di fare controlli, logging, modifiche o altre reazioni quando il valore cambia.

2. Definizione e sintassi

Una proprietà è un membro speciale della classe che sembra quasi un campo, ma in realtà sotto il cofano è una coppia di metodi speciali: getter (prendi il valore) e setter (imposta il valore). Con una proprietà puoi:

  • Permettere (o vietare) la lettura/scrittura dei dati;
  • Aggiungere validazione o logica quando accedi ai dati;
  • Nascondere il campo interno e magari salvare il valore da qualche altra parte.

La proprietà si dichiara quasi come un campo, solo che ci sono le parentesi graffe e le parole chiave get e set dentro.


[modificatore_accesso] tipo NomeProprietà
{
    get { ... }
    set { ... }
}
Template dichiarazione proprietà

Ecco un esempio per la nostra classe Dog:

public class Dog
{
    private string _name; // campo interno (private!)

    public string Name
    {
        get { return _name; }  // "getter": prendi il nome
        set { _name = value; } // "setter": assegna il nome
    }
}

Nota: l'underscore si usa di solito per i campi privati (_name). È uno standard di stile in C#.

3. Come funziona una proprietà

La proprietà è una specie di "guardiano" che sta tra i dati interni dell'oggetto e il mondo esterno. Esempio:

Dog dog = new Dog();
dog.Name = "Sharik";
Console.WriteLine(dog.Name);

Spiegazione:

  • Quando il programma arriva alla riga dog.Name = "Sharik"; — in quel momento viene chiamato il metodo set della proprietà, e puoi aggiungere lì qualsiasi controllo (tipo verificare che il nome non sia vuoto).
  • Al momento di Console.WriteLine(dog.Name); viene chiamato il metodo get, che semplicemente restituisce il valore attuale o, se vuoi, qualcosa calcolato al volo.

Sembra un campo normale, ma in realtà qui è tutto sotto controllo!

4. Perché le proprietà sono una "Best Practice"

Nella maggior parte dei casi non diamo accesso diretto ai campi interni di un oggetto. Anche se ora ti sembra che i controlli non servano, abituarsi a incapsulare i dati nelle proprietà ti salva la vita quando cambiano le regole del gioco.

Esempio di "validazione" al momento dell'assegnazione:


public class Dog
{
    private string _name;

    public string Name
    {
        get { return _name; }
        set
        {
            if (string.IsNullOrWhiteSpace(value))
            {
                throw new ArgumentException("Il nome del cane non può essere vuoto!");
            }
            _name = value;
        }
    }
}

Ora una cosa del genere:

dog.Name = ""; // Lancia un'eccezione!

… protegge il nostro oggetto da valori assurdi.

5. Proprietà: sola lettura, sola scrittura e normali

A volte vuoi permettere solo di leggere il valore (tipo, il cane ha solo l'anno di nascita, non puoi cambiarlo), o al contrario — solo impostarlo (raramente, ma magari vuoi fare qualcosa di misterioso).

  • Sola lettura: scrivi solo get, togli set.
  • Sola scrittura: scrivi solo set, togli get.

Esempi:

public class Dog
{
    private int _birthYear = 2018;

    // Sola lettura
    public int BirthYear
    {
        get { return _birthYear; }
    }

    // Sola scrittura (si vede raramente)
    public string Secret
    {
        set { /* facciamo qualcosa con value */ }
    }
}

6. Proprietà vs campi

Campo Proprietà
Sintassi
public string Name;
public string Name { get; set; }
Accesso Diretto Tramite get/set
Validazione No Puoi aggiungere in set/get
Estendibilità No Puoi modificare in qualsiasi momento
Integrazione IDE Visti come campi Visti come proprietà (importante per i framework)

Illustrazione: Come funziona una proprietà

sequenceDiagram
participant User as Utente dell'oggetto
participant Dog as Oggetto Dog
participant Field as Campo privato _name

User->>Dog: dog.Name = "Ryzhik"
Dog->>Dog: set Name("Ryzhik")
Dog->>Field: _name = "Ryzhik"

User->>Dog: print(dog.Name)
Dog->>Dog: get Name()
Dog->>Field: legge _name
Dog->>User: restituisce "Ryzhik"

7. Errori tipici e sfumature

Vediamo dove possono nascondersi le trappole.

Errore comune — confondere campi e proprietà, esponendo accidentalmente dati privati:

public string name; // Questo è un campo! Si vede ovunque, pericoloso!

Meglio così:

private string _name;
public string Name
{
    get { return _name; }
    set { _name = value; }
}

Proprietà statiche esistono per salvare valori comuni a tutti gli oggetti. Ma usale con attenzione.

Curiosità: se una proprietà ha solo get e nessun costruttore, non puoi cambiarla mai — questa cosa si chiama immutable property e viene usata un sacco nei design moderni (ci torneremo nelle lezioni su record e immutabilità dei dati).

Commenti
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION