TOC

This article has been localized into Italian by the community.

Classi:

Proprietà

Nell'articolo precedente, abbiamo discusso di fields . Sono come variabili globali per una classe, permettendoti di accedervi da tutti i metodi. Abbiamo anche discusso brevemente del fatto che i campi possono essere accessibili da altre classi se sono contrassegnati come public , ma che generalmente non è raccomandato. Per variabili field a cui desideri accedere al di fuori della tua classe, devi invece utilizzare le properties.

Quando dichiari un field come pubblico, stai fornendo un accesso completo ad esso dall'esterno - altre classi possono fare ciò che vogliono con esso, senza alcun preavviso alla classe dichiarante. Proprietà restituisce il controllo alla classe dichiarante, specificando se un field è di sola lettura o di scrittura e persino consentendo alla classe dichiarante di controllare e manipolare il valore prima di restituirlo o assegnarlo al field.

Una properties assomiglia un po' a un crossover tra un field e un metodo, perché è dichiarata molto simile a un field con visibilità, un tipo di dati e un nome, ma ha anche un corpo, come un metodo, per controllarne il comportamento:

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

Nota le speciali parole chiave get (ottieni) e set (imposta). Sono utilizzati esclusivamente per le properties, per controllare il comportamento durante la lettura (acquisizione(get)) e la scrittura (impostazione(set)) del field. Puoi avere le properties solo con un'implementazione get o set, per creare properties di sola lettura o di sola scrittura e puoi persino controllare la visibilità delle implementazioni get o set, ad esempio per creare una proprietà che può essere letta da qualsiasi luogo (pubblico) ma modificata solo dall'interno della classe dichiarante (privato).

Avrai notato sicuramente che mi riferisco a un campo called _name. Dovrai dichiararlo anche nella tua classe, in modo che la tua properties possa utilizzarlo. Un modello di utilizzo comune per field e properties sarà simile al seguente:

private string _name = "John Doe";

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

Ora hai visto come funzionano il field e la proprieties: il metodo get restituirà il valore del field _name , mentre il metodo set assegnerà il valore passato al field _name . Nel metodo set, utilizziamo il valore della parola chiave speciale che, in questa situazione specifica, farà riferimento al valore passato alla properties.

Quindi, è praticamente basilare e, a questo punto, non facciamo nulla che non possa essere realizzato con un semplice field pubblico. Ma in un secondo momento, potresti decidere di voler avere un maggiore controllo sul modo in cui altre classi possono lavorare con il nome e poiché hai implementato questo come properties, sei libero di modificare l'implementazione senza disturbare nessuno che usa la tua classe. Ad esempio, la properties Name potrebbe essere modificata in questo modo:

private string _name = "John Doe";

public string Name
{
	get 
	{
		return _name.ToUpper();
	}
	set 
	{
		if(!value.Contains(" "))
			throw new Exception("Please specify both first and last name!");
		_name = value; 
	}
}

Il metodo get ora impone che il valore restituito sia sempre in MAIUSCOLO, indipendentemente dal caso in cui sia presente il field di supporto (_name). Nel metodo set , abbiamo aggiunto un un paio di righe di codice per verificare se il valore passato contiene uno spazio, perché abbiamo deciso che il nome deve sempre consistere sia di un nome che di un cognome - in caso contrario, viene generata un'eccezione. Tutto ciò è molto rozzo e semplificato, ma dovrebbe illustrare l'intero livello di controllo che si ottiene quando si utilizzano le properties.

Proprietà di sola lettura

La maggior parte delle proprietà che incontrerai negli esempi di questo corso saranno sia leggibili sia scrivibili perché di solito vengono usate in questo modo, ma non deve essere sempre così. Per cominciare, puoi dichiarare una proprietà con solo il metodo get, come nell'esempio:

private string _name = "John Doe";

public string Name
{
	get { return _name; }
}

In questo caso, non puoi più cambiare la proprietà "Name", puoi solo leggerla e il compilatore segnalerà un errore se proverai ad assegnarle un valore. Puoi comunque ancora cambiarle il valore dall'interno della classe, in quanto puoi semplicemente assegnare un nuovo valore al field di supporto "_name". Farlo in questo modo però nega uno dei più grandi vantaggi delle proprietà: l'abilità di poter sempre controllare se un valore può essere accettato. Dato che ne abbiamo già parlato, il metodo set è un ottimo modo di eseguire la convalida del valore, ma se assegni un nuovo valore al field "_name" da punti diversi, proprio perché la proprietà è di sola lettura, non avrai questa convalida.

Fortunatamente per noi, il C# offre una soluzione a questo: puoi definire un metodo set sulla proprietà ma limitare la sua visibilità, usando ad esempio le keyword private o protected. Questo ti darà i vantaggi di entrambi, in quanto puoi sempre assegnare un valore alla proprietà dall'interno della classe (o di qualsiasi classe ereditata se usi la keywork "protected") e fartelo convalidare. Ecco un esempio:

private string _name = "John Doe";

public string Name
{
	get { return _name; }

	private set
	{
		if(IsValidName(value))
			this._name = value;
	}
}

public bool IsValidName(string name)
{
	return name.EndsWith("Doe");

}

La differenza sostanziale qui è semplicemente la parola chiave "private" davanti alla parola chiave "set" e, come menzionato, puoi sostituirla con (per esempio) "protected" o "internal", in base alle tue necessità.

Proprietà auto-implementate

In alcuni casi, non è necessario tutto il controllo su un field e può sembrare ingombrante implementare sia un field che una properties con i metodi get e set che non fanno nulla oltre a quello che abbiamo visto nel primo esempio. Potresti essere tentato di dichiarare semplicemente la tua variabile come un campo pubblico per evitare tutta questa seccatura extra. Ma non farlo! Fortunatamente per tutti noi, Microsoft ha deciso di aggiungere properties implementate automaticamente in C # versione 3, che ti farà risparmiare diverse righe di codice. Basta considerarne la differenza:

Properties regolare con un field di supporto dichiarato:

private string _name;

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

Lo stesso identico comportamento, ma con una properties implementata automaticamente:

public string Name { get; set; }

Si noti che i metodi get e set sono vuoti e che non viene dichiarato alcun field di supporto privato - in altre parole, ora possiamo ottenere lo stesso comportamento del primo esempio ma con una sola riga di codice! Tieni presente che il field di supporto privato esisterà ancora in fase di esecuzione - verrà implementato automaticamente dal compilatore, come suggerisce il nome. Se in seguito dovessi decidere di avere bisogno di un maggiore controllo su questa specifica properties, puoi semplicemente cambiarla in una normale combinazione field / properties con l'implementazione desiderata dei metodi get e set.

Si noti che rimane ancora un importante meccanismo di controllo dalle properties regolari quando si utilizzano le properties implementate automaticamente: è possibile tralasciare la parola chiave impostata per creare una properties di sola lettura, ad es. come questo:

public string ReadOnlyProperty { get; }

Le properties di sola scrittura non sono consentite quando si utilizzano le properties implementate automaticamente.

Proprietà auto-implementate con valori predefiniti

Prima della versione 6 di C #, non era possibile definire un valore predefinito per una properties implementata automaticamente; per questo, sarebbe necessario un field di supporto dichiarato, che consentirebbe di inizializzare la variabile con un valore:

private string _name = "John Doe";

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

Ma in C # versione 6, Microsoft ha finalmente aggiunto la possibilità di inizializzare una proprietà implementata automaticamente con un valore predefinito, come questo:

public string Name { get; set; } = "John Doe";

Proprietà con corpo di espressione (expression-bodied)

Un'altra caratteristica delle proprietà che Microsoft ha implementato in C# 6.0 e 7.0, sono i membri con corpo di espressione. Permettono semplicemente di scrivere espressioni di una linea sola, per proprietà e metodi. In questo caso, vediamo come usarli per i metodi get/set in modo che occupino meno spazio e richiedano meno digitazione:

private string name;
public string Name
{
	get => name;
	set => name = value;
}

Se la proprietà è di sola lettura (read-only), la sintassi può essere accorciata:

public string Name => "John Doe";

Naturalmente, funziona anche se si deve effettivamente fare qualcosa prima di ritornare il valore, come questo:

public string Name { get; set; } = "John Doe";

public string FirstName => this.Name.Substring(0, this.Name.IndexOf(" "));

Come si può vedere, questo permette di definire un metodo get, ma senza le parole chiave get ereturn, mentre ci spinge a mantenere tutto in una linea anziché linee multiple.

Riepilogo

Le proprietà danno alla classe un maggior controllo su come accedere ai campi e su come manipolarli e dovrebbero sempre essere usati quando si vuole dare l'accesso ai campi dall'esterno della classe dichiarante.


This article has been fully translated into the following languages: Is your preferred language not on the list? Click here to help us translate this article into your language!