原文地址https://docs.microsoft.com/zh-cn/dotnet/csharp/programming-guide/statements-expressions-operators/expression-bodied-members
通过表达式主体定义,可采用非常简洁的可读形式提供成员的实现。 只要任何支持的成员(如方法或属性)的逻辑包含单个表达式,就可以使用表达式主体定义。 表达式主体定义具有下列常规语法:
C#
member => expression;
其中“expression”是有效的表达式。
C# 6 中引入了针对方法和属性 Get 访问器的表达式主体定义支持,并在 C# 7.0 中进行了扩展。 表达式主体定义可用于下表列出的类型成员:
| 成员 | 开始提供支持的版本 |
|---|---|
| 方法 | C# 6 |
| 构造函数 | C# 7.0 |
| 终结器 | C# 7.0 |
| 属性 Get | C# 6 |
| 属性 Set | C# 7.0 |
| 索引器 | C# 7.0 |
方法
expression-bodied 方法包含单个表达式,它返回的值的类型与方法的返回类型匹配;或者,对于返回 void 的方法,其表达式则执行某些操作。 例如,替代 ToString 方法的类型通常包含单个表达式,该表达式返回当前对象的字符串表示形式。
下面的示例定义 Person 类,该类通过表达式主体定义替代 ToString。 它还定义向控制台显示名称的 DisplayName 方法。 请注意,ToString 表达式主体定义中未使用 return 关键字。
C#
-
using System; -
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(); -
} -
}
有关详细信息,请参阅方法(C# 编程指南)。
构造函数
构造函数的表达式主体定义通常包含单个赋值表达式或一个方法调用,该方法调用可处理构造函数的参数,也可初始化实例状态。
以下示例定义 Location 类,其构造函数具有一个名为“name”的字符串参数。 表达式主体定义向 Name 属性分配参数。
C#
-
public class Location -
{ -
private string locationName; -
public Location(string name) => Name = name; -
public string Name -
{ -
get => locationName; -
set => locationName = value; -
} -
}
有关详细信息,请参阅构造函数(C# 编程指南)。
终结器
终结器的表达式主体定义通常包含清理语句,例如释放非托管资源的语句。
下面的示例定义了一个终结器,该终结器使用表达式主体定义来指示已调用该终结器。
C#
-
using System; -
public class Destroyer -
{ -
public override string ToString() => GetType().Name; -
~Destroyer() => Console.WriteLine($"The {ToString()} destructor is executing."); -
}
有关详细信息,请参阅终结器(C# 编程指南)。
属性 Get 语句
如果选择自行实现属性 Get 访问器,可以对只返回属性值的单个表达式使用表达式主体定义。 请注意,未使用 return 语句。
下面的示例定义 Location.Name 属性,其属性 Get 访问器返回支持该属性的私有 locationName 字段的值。
C#
-
public class Location -
{ -
private string locationName; -
public Location(string name) => Name = name; -
public string Name -
{ -
get => locationName; -
set => locationName = value; -
} -
}
不使用显式 set 语句也可实现使用表达式主体定义的只读属性。 语法为:
C#复制
PropertyName => returnValue;
下面的示例定义 Location 类,其只读 Name 属性以表达式主体定义的形式实现,该表达式主体定义返回私有 locationName 字段值。
C#
-
public class Location -
{ -
private string locationName; -
public Location(string name) => locationName = name; -
public string Name => locationName; -
}
有关详细信息,请参阅属性(C# 编程指南)。
属性 Set 语句
如果选择自行实现属性 Set 访问器,可以对单行表达式使用表达式主体定义,该单行表达式用于对支持该属性的字段赋值。
下面的示例定义 Location.Name 属性,其属性 Set 语句将其输入参数赋给支持该属性的私有 locationName 字段。
C#
-
public class Location -
{ -
private string locationName; -
public Location(string name) => Name = name; -
public string Name -
{ -
get => locationName; -
set => locationName = value; -
} -
}
有关详细信息,请参阅属性(C# 编程指南)。
索引器
与属性一样,如果索引器的 Get 访问器包含单个返回值的语句或其 Set 访问器执行简单的赋值,则 Get 和 Set 访问器包含表达式主体定义。
下面的示例定义名为 Sports 的类,其中包含一个内部 String 数组,该数组包含大量体育运动的名称。索引器的 Get 和 Set 访问器都以表达式主体定义的形式实现。
C#
-
using System; -
using System.Collections.Generic; -
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; -
}