Membri con corpo di espressione (Guida per programmatori C#)
Le definizioni di corpo dell'espressione consentono di fornire l'implementazione di un membro in modo conciso e leggibile. È possibile usare una definizione di corpo di espressione ogni volta che la logica per un membro supportato, ad esempio un metodo o proprietà, è costituita da un'unica espressione. Una definizione di corpo di espressione presenta la seguente sintassi generale:
member => expression;
dove expression è un'espressione valida.
Le definizioni di corpo dell'espressione possono essere usate con i membri dei tipi seguenti:
Metodi
Un metodo con corpo di espressione è costituito da una singola espressione che restituisce un valore il cui tipo corrisponde al tipo restituito del metodo oppure, per i metodi che restituiscono void
, che esegue una determinata operazione. Ad esempio, i tipi che eseguono l'override del metodo ToString di solito includono una singola espressione che restituisce la rappresentazione di stringa dell'oggetto corrente.
L'esempio seguente definisce una classe Person
che esegue l'override del metodo ToString con una definizione di corpo di espressione. Definisce inoltre un metodo DisplayName
che visualizza un nome nella console. La parola chiave return
non viene usata nella definizione del corpo dell'espressione ToString
.
using System;
namespace ExpressionBodiedMembers;
public class Person
{
public Person(string firstName, string lastName)
{
fname = firstName;
lname = lastName;
}
private string fname;
private string lname;
public override string ToString() => $"{fname} {lname}".Trim();
public void DisplayName() => Console.WriteLine(ToString());
}
class Example
{
static void Main()
{
Person p = new Person("Mandy", "Dejesus");
Console.WriteLine(p);
p.DisplayName();
}
}
Per altre informazioni, vedere Metodi (Guida per programmatori C#).
Proprietà di sola lettura
È possibile usare una definizione di corpo dell'espressione per implementare una proprietà di sola lettura. A questo scopo, usare la sintassi seguente:
PropertyType PropertyName => expression;
L'esempio seguente definisce una classe Location
la cui proprietà Name
di sola lettura viene implementata come definizione del corpo dell'espressione che restituisce il valore del campo locationName
privato:
public class Location
{
private string locationName;
public Location(string name)
{
locationName = name;
}
public string Name => locationName;
}
Per altre informazioni sulle proprietà, vedere Proprietà (Guida per programmatori C#).
Proprietà
È possibile usare le definizioni di corpo dell'espressione per implementare le funzioni di accesso get
e set
delle proprietà. Nell'esempio riportato di seguito viene illustrato come procedere:
public class Location
{
private string locationName;
public Location(string name) => Name = name;
public string Name
{
get => locationName;
set => locationName = value;
}
}
Per altre informazioni sulle proprietà, vedere Proprietà (Guida per programmatori C#).
Eventi
Analogamente, i add
di eventi e le funzioni di accesso remove
possono essere con corpo di espressione:
public class ChangedEventArgs : EventArgs
{
public required int NewValue { get; init; }
}
public class ObservableNum(int _value)
{
public event EventHandler<ChangedEventArgs> ChangedGeneric = default!;
public event EventHandler Changed
{
// Note that, while this is syntactically valid, it won't work as expected because it's creating a new delegate object with each call.
add => ChangedGeneric += (sender, args) => value(sender, args);
remove => ChangedGeneric -= (sender, args) => value(sender, args);
}
public int Value
{
get => _value;
set => ChangedGeneric?.Invoke(this, new() { NewValue = (_value = value) });
}
}
Per altre informazioni sugli eventi, vedere Eventi (Guida per programmatori C#).
Costruttori
Una definizione di corpo di espressione per un costruttore in genere è costituita da una singola espressione di assegnazione o da una chiamata al metodo che gestisce gli argomenti del costruttore o inizializza lo stato dell'istanza.
L'esempio seguente definisce una classe Location
il cui costruttore ha un solo parametro di stringa denominato name. La definizione del corpo dell'espressione assegna l'argomento alla proprietà Name
.
public class Location
{
private string locationName;
public Location(string name) => Name = name;
public string Name
{
get => locationName;
set => locationName = value;
}
}
Per altre informazioni, vedere Costruttori (Guida per programmatori C#).
Finalizzatori
Una definizione di corpo di espressione per un finalizzatore in genere contiene istruzioni di pulitura, ad esempio le istruzioni che rilasciano risorse non gestite.
L'esempio seguente definisce un finalizzatore che usa una definizione di corpo di espressione per indicare che è stato chiamato il finalizzatore.
public class Destroyer
{
public override string ToString() => GetType().Name;
~Destroyer() => Console.WriteLine($"The {ToString()} finalizer is executing.");
}
Per altre informazioni, vedere Finalizzatori (Guida per programmatori C#).
Indicizzatori
Come per le proprietà, le funzioni di accesso get
e set
degli indicizzatori sono costituite da definizioni di corpo dell'espressione se get
è costituita da una singola espressione che restituisce un valore o set
esegue un'assegnazione semplice.
L'esempio seguente definisce una classe denominata Sports
che include una matrice String interna contenente i nomi di alcuni sport. Le funzioni di accesso get
e set
degli indicizzatori sono entrambe implementate come definizioni di corpo dell'espressione.
using System;
using System.Collections.Generic;
namespace SportsExample;
public class Sports
{
private string[] types = [ "Baseball", "Basketball", "Football",
"Hockey", "Soccer", "Tennis",
"Volleyball" ];
public string this[int i]
{
get => types[i];
set => types[i] = value;
}
}
Per altre informazioni, vedere Indicizzatori (Guida per programmatori C#).