Compartilhar via


Membros aptos para expressão (Guia de Programação em C#)

As definições do corpo da expressão permitem que você forneça a implementação de um membro de forma concisa e legível. Você pode usar uma definição de corpo da expressão sempre que a lógica para qualquer membro com suporte, como um método ou propriedade, consiste em uma única expressão. Uma definição de corpo da expressão tem a seguinte sintaxe geral:

member => expression;

em que expression é uma expressão válida.

As definições do corpo da expressão podem ser usadas com os seguintes membros de tipo:

Métodos

Um método apto para 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 executam uma operação. Por exemplo, os tipos que substituem o método ToString normalmente incluem uma única expressão que retorna a representação da cadeia de caracteres do objeto atual.

O exemplo a seguir define uma classe Person que substitui o método ToString por uma definição de corpo da expressão. Ele também define um método DisplayName que exibe um nome para o console. A palavra-chave return não é utilizada na definição do corpo da expressão 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();
   }
}

Para obter mais informações, consulte Métodos (Guia de Programação em C#).

Propriedades somente leitura

Você pode usar a definição de corpo da expressão para implementar uma propriedade somente leitura. Para isso, use a seguinte sintaxe:

PropertyType PropertyName => expression;

O exemplo a seguir define uma classe Location cuja propriedade somente leitura Name é implementada como uma definição de corpo da expressão que retorna o valor do campo locationName particular:

public class Location
{
   private string locationName;

   public Location(string name)
   {
      locationName = name;
   }

   public string Name => locationName;
}

Para obter mais informações sobre as propriedades, confira Propriedades (Guia de Programação em C#).

Propriedades

Você pode usar as definições de corpo da expressão para implementar a propriedade get e os acessadores set. 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 as propriedades, confira Propriedades (Guia de Programação em C#).

Eventos

Da mesma forma, os acessadores de evento add e remove podem ter corpo de 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 da expressão para um construtor normalmente consiste em uma expressão de atribuição simples 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 classe Location cujo construtor tem um único parâmetro de cadeia de caracteres chamado nome. A definição de corpo da expressão atribui o argumento à propriedade Name.

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 da 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 da 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 as propriedades, os acessadores get e set do indexador consistirão em definições de corpo da expressão se o acessador get consistir em uma única expressão que retorna um valor ou o acessador set executar 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. Os acessadores get e set do indexador são implementados como definições de corpo da 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#).

Confira também