Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
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. Include inoltre diversi metodi che accettano parametri, dimostrando il funzionamento dei membri con corpo di espressione con i parametri del metodo. La return
parola chiave non viene usata in nessuna delle definizioni del corpo dell'espressione.
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());
// Expression-bodied methods with parameters
public string GetFullName(string title) => $"{title} {fname} {lname}";
public int CalculateAge(int birthYear) => DateTime.Now.Year - birthYear;
public bool IsOlderThan(int age) => CalculateAge(1990) > age;
public string FormatName(string format) => format.Replace("{first}", fname).Replace("{last}", lname);
}
class Example
{
public static void Main()
{
Person p = new Person("Mandy", "Dejesus");
Console.WriteLine(p);
p.DisplayName();
// Examples with parameters
Console.WriteLine(p.GetFullName("Dr."));
Console.WriteLine($"Age: {p.CalculateAge(1990)}");
Console.WriteLine($"Is older than 25: {p.IsOlderThan(25)}");
Console.WriteLine(p.FormatName("Last: {last}, First: {first}"));
}
}
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;
}
}
// Example with multiple parameters
public class Point
{
public double X { get; }
public double Y { get; }
// Constructor with multiple parameters
public Point(double x, double y) => (X, Y) = (x, y);
// Constructor with single parameter (creates point at origin on axis)
public Point(double coordinate) => (X, Y) = (coordinate, 0);
}
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
. L'esempio mostra anche una Point
classe con costruttori che accettano più parametri, dimostrando il funzionamento dei costruttori con corpo di espressione con combinazioni di parametri diverse.
public class Location
{
private string locationName;
public Location(string name) => Name = name;
public string Name
{
get => locationName;
set => locationName = value;
}
}
// Example with multiple parameters
public class Point
{
public double X { get; }
public double Y { get; }
// Constructor with multiple parameters
public Point(double x, double y) => (X, Y) = (x, y);
// Constructor with single parameter (creates point at origin on axis)
public Point(double coordinate) => (X, Y) = (coordinate, 0);
}
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#).