Membros com corpo de expressão (guia de programação em C#)
As definições do corpo da expressão permitem fornecer a implementação de um membro de forma concisa e legível. Você pode usar uma definição de corpo de expressão sempre que a lógica para qualquer membro suportado, como um método ou propriedade, consistir em uma única expressão. Uma definição de corpo de expressão tem a seguinte sintaxe geral:
member => expression;
onde expressão é uma expressão válida.
As definições de corpo de expressão podem ser usadas com os seguintes membros de tipo:
Métodos
Um método com corpo de expressão consiste em uma única expressão que retorna um valor cujo tipo corresponde ao tipo de retorno do método ou, para métodos que retornam void
, que executa alguma operação. Por exemplo, os tipos que substituem o ToString método normalmente incluem uma única expressão que retorna a representação de cadeia de caracteres do objeto atual.
O exemplo a seguir define uma Person
classe que substitui o ToString método por uma definição de corpo de expressão. Ele também define um DisplayName
método que exibe um nome para o console. A return
palavra-chave não é usada na definição do corpo da ToString
expressão.
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();
}
}
Para obter mais informações, consulte Métodos (Guia de Programação em C#).
Propriedades só de leitura
Você pode usar a definição de corpo de expressão para implementar uma propriedade somente leitura. Para fazer isso, use a seguinte sintaxe:
PropertyType PropertyName => expression;
O exemplo a seguir define uma Location
classe cuja propriedade somente Name
leitura é implementada como uma definição de corpo de expressão que retorna o valor do campo privado locationName
:
public class Location
{
private string locationName;
public Location(string name)
{
locationName = name;
}
public string Name => locationName;
}
Para obter mais informações sobre propriedades, consulte Propriedades (Guia de Programação em C#).
Propriedades
Você pode usar definições de corpo de expressão para implementar propriedades get
e set
acessadores. O exemplo a seguir demonstra como fazer isso:
public class Location
{
private string locationName;
public Location(string name) => Name = name;
public string Name
{
get => locationName;
set => locationName = value;
}
}
Para obter mais informações sobre propriedades, consulte Propriedades (Guia de Programação em C#).
evento
Da mesma forma, eventos add
e remove
acessadores podem ser corporizados por expressão:
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) });
}
}
Para obter mais informações sobre eventos, consulte Eventos (Guia de Programação em C#).
Construtores
Uma definição de corpo de expressão para um construtor normalmente consiste em uma única expressão de atribuição ou uma chamada de método que manipula os argumentos do construtor ou inicializa o estado da instância.
O exemplo a seguir define uma Location
classe cujo construtor tem um único parâmetro string chamado name. A definição do corpo da expressão atribui o argumento à Name
propriedade.
public class Location
{
private string locationName;
public Location(string name) => Name = name;
public string Name
{
get => locationName;
set => locationName = value;
}
}
Para obter mais informações, consulte Construtores (Guia de Programação em C#).
Finalizadores
Uma definição de corpo de expressão para um finalizador normalmente contém instruções de limpeza, como instruções que liberam recursos não gerenciados.
O exemplo a seguir define um finalizador que usa uma definição de corpo de expressão para indicar que o finalizador foi chamado.
public class Destroyer
{
public override string ToString() => GetType().Name;
~Destroyer() => Console.WriteLine($"The {ToString()} finalizer is executing.");
}
Para obter mais informações, consulte Finalizadores (Guia de Programação em C#).
Indexadores
Como acontece com as propriedades, indexador get
e set
acessadores consistem em definições de corpo de expressão se o get
acessador consiste em uma única expressão que retorna um valor ou o set
acessador executa uma atribuição simples.
O exemplo a seguir define uma classe chamada Sports
que inclui uma matriz interna String que contém os nomes de alguns esportes. Tanto o indexador get
quanto set
os acessadores são implementados como definições de corpo de expressão.
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;
}
}
Para obter mais informações, consulte Indexadores (Guia de Programação em C#).