共用方式為


運算式主體成員 (C# 程式設計手冊)

運算式主體定義可讓您以簡潔且可讀的形式提供成員的實作。 只要任何所支援成員 (例如方法或屬性) 的邏輯包含單一運算式,就可以使用運算式主體定義。 運算式主體定義的一般語法如下︰

member => expression;

其中 expression 是有效的運算式。

運算式主體定義可以與下列型別成員搭配使用:

方法

運算式主體方法包含傳回型別符合方法傳回型別之值的單一運算式,或是傳回可執行某項作業之 void 的方法。 例如,覆寫 ToString 方法的類型通常會包括可傳回目前物件之字串表示的單一運算式。

下列範例定義 Person 類別,以將 ToString 方法覆寫為運算式主體定義。 它也會定義 DisplayName 方法,以向主控台顯示名稱。 此外,它包含數個採用參數的方法,示範表達式主體成員如何使用方法參數。 關鍵詞 return 不會用於任何表達式主體定義中。

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

如需詳細資訊,請參閱方法 (C# 程式設計手冊)

唯讀屬性

您可以使用運算式主體定義來實作唯讀屬性。 若要這麼做,請使用下列語法:

PropertyType PropertyName => expression;

下列範例會定義 Location 類別,其唯讀 Name 屬性會實作為可傳回私用 locationName 欄位值的運算式主體定義:

public class Location
{
   private string locationName;

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

   public string Name => locationName;
}

如需屬性的詳細資訊,請參閱屬性 (C# 程式設計手冊)

屬性

您可以使用運算式主體定義來實作屬性 getset 存取子。 下列範例示範如何進行這項操作:

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

如需屬性的詳細資訊,請參閱屬性 (C# 程式設計手冊)

事件

同樣地,事件 addremove 存取子可以是運算式主體:

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

如需事件的詳細資訊,請參閱 事件 (C# 程式設計手冊)

建構函式

建構函式的運算式主體定義通常會包含單一指派運算式或方法呼叫,以處理建構函式的引數,或初始化執行個體狀態。

下列範例定義 Location 類別,這個類別的建構函式包含名為 name 的單一字串參數。 運算式主體定義會將引數指派給 Name 屬性。 此範例也會示範具有 Point 採用多個參數之建構函式的類別,示範運算式主體建構函式如何使用不同的參數組合。

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

如需詳細資訊,請參閱建構函式 (C# 程式設計手冊)

完成項

完成項的運算式主體定義通常包含清除陳述式,例如,發行不受管理資源的陳述式。

下列範例定義完成項,以使用運算式主體定義來指出已呼叫完成項。

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

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

如需詳細資訊,請參閱完成項 (C# 程式設計手冊)

索引子

如同屬性,如果 get 存取子包含傳回值的單一陳述式,或 set 存取子執行簡單指派,則索引子的 getset 存取子會包含運算式主體定義。

下列範例會定義名為 Sports 的類別,這個類別包括內含一些運動名稱的內部 String 陣列。 索引子 getset 存取子會實作為運算式主體定義。

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

如需詳細資訊,請參閱索引子 (C# 程式設計手冊)

另請參閱