Editéieren

Deelen iwwer


Expression-bodied members (C# programming guide)

Expression body definitions let you provide a member's implementation in a concise, readable form. You can use an expression body definition whenever the logic for any supported member, such as a method or property, consists of a single expression. An expression body definition has the following general syntax:

member => expression;

where expression is a valid expression.

Expression body definitions can be used with the following type members:

Methods

An expression-bodied method consists of a single expression that returns a value whose type matches the method's return type, or, for methods that return void, that performs some operation. For example, types that override the ToString method typically include a single expression that returns the string representation of the current object.

The following example defines a Person class that overrides the ToString method with an expression body definition. It also defines a DisplayName method that displays a name to the console. The return keyword is not used in the ToString expression body definition.

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();
   }
}

For more information, see Methods (C# Programming Guide).

Read-only properties

You can use expression body definition to implement a read-only property. To do that, use the following syntax:

PropertyType PropertyName => expression;

The following example defines a Location class whose read-only Name property is implemented as an expression body definition that returns the value of the private locationName field:

public class Location
{
   private string locationName;

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

   public string Name => locationName;
}

For more information about properties, see Properties (C# Programming Guide).

Properties

You can use expression body definitions to implement property get and set accessors. The following example demonstrates how to do that:

public class Location
{
   private string locationName;

   public Location(string name) => Name = name;

   public string Name
   {
      get => locationName;
      set => locationName = value;
   }
}

For more information about properties, see Properties (C# Programming Guide).

Events

Similarly, event add and remove accessors can be expression-bodied:

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) });
   }
}

For more information about events, see Events (C# Programming Guide).

Constructors

An expression body definition for a constructor typically consists of a single assignment expression or a method call that handles the constructor's arguments or initializes instance state.

The following example defines a Location class whose constructor has a single string parameter named name. The expression body definition assigns the argument to the Name property.

public class Location
{
   private string locationName;

   public Location(string name) => Name = name;

   public string Name
   {
      get => locationName;
      set => locationName = value;
   }
}

For more information, see Constructors (C# Programming Guide).

Finalizers

An expression body definition for a finalizer typically contains cleanup statements, such as statements that release unmanaged resources.

The following example defines a finalizer that uses an expression body definition to indicate that the finalizer has been called.

public class Destroyer
{
   public override string ToString() => GetType().Name;

   ~Destroyer() => Console.WriteLine($"The {ToString()} finalizer is executing.");
}

For more information, see Finalizers (C# Programming Guide).

Indexers

Like with properties, indexer get and set accessors consist of expression body definitions if the get accessor consists of a single expression that returns a value or the set accessor performs a simple assignment.

The following example defines a class named Sports that includes an internal String array that contains the names of some sports. Both the indexer get and set accessors are implemented as expression body definitions.

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;
   }
}

For more information, see Indexers (C# Programming Guide).

See also