首页 / C# 入门教程 / 表达式体成员

C# 入门教程

表达式体成员

本教程共 100 篇 · 第 53 篇 · 更新于 2026-07-31 · 约 7 分钟阅读

C#C# 入门教程编程语言表达式体语法糖

53. 表达式体成员

本节目标:学完你能用 => 把简单成员写成一行,知道哪些地方适合、哪些地方别滥用。

有些成员的逻辑只有一句话:方法算个平方、属性返回一个拼接字符串、构造器给字段赋值。C# 允许用 =>(lambda 运算符,也叫「火箭运算符」)把这些成员写成表达式体(expression-bodied),省掉大括号和 return

可以把表达式体想象成「电梯直达」:普通成员写法像走楼梯(先进门、再上楼、再出来),表达式体像按一下直接到层——目的地一样,只是更短。但楼梯也有楼梯的好:路远、弯多时,还是走楼梯稳当。

一、表达式体方法

最常用在方法上。左边是签名,右边是一个表达式,编译器自动把它当返回值:

namespace CSharpDemo;

int Square(int x) => x * x;
void Print(string s) => Console.WriteLine(s);

Console.WriteLine(Square(6)); // 36
Print("你好");

右边只能是一个表达式,不能是一串语句。想写多步逻辑,还是得用普通方法体。

为什么省得漂亮

它本质是语法糖,编译出的 IL 和写 { return ...; } 完全一样。价值在于少噪音:一眼就能看出「这个方法就干这一件事」。对读代码的人来说,「短」降低了认知负担。

二、表达式体属性

只读属性特别适合这种写法,getter 直接跟一个表达式:

namespace CSharpDemo;

class Person
{
    public string Name { get; set; } = "匿名";
    public int BirthYear { get; set; }
    public int Age => DateTime.Now.Year - BirthYear;
}

var p = new Person { Name = "小明", BirthYear = 2000 };
Console.WriteLine($"{p.Name} 今年 {p.Age} 岁");

Age 没有存字段,每次访问现算。它等价于 get { return ...; },只是更短。

Note

表达式体属性只能是只读(只有 get)。需要 set 时仍用普通属性;不过 C# 14 起可以配合 field 关键字写 set => field = value,后面会提。

三、表达式体构造器与析构器

构造器也能用 => 给字段赋值:

namespace CSharpDemo;

class Person
{
    public string Name { get; }
    public Person(string name) => Name = name;
}

var p = new Person("小红");
Console.WriteLine(p.Name); // 小红

终结器(finalizer,也叫析构器)同理:~Person() => Console.WriteLine("释放");。它们不带 return,右边是执行语句。

四、表达式体索引器与运算符

索引器返回元素,运算符返回新对象,写成表达式体都很自然:

namespace CSharpDemo;

class Bag
{
    private string[] items = ["苹果", "香蕉", "橙子"];
    public string this[int i] => items[i];
}

class Point
{
    public int X { get; }
    public int Y { get; }
    public Point(int x, int y) => (X, Y) = (x, y);
    public static Point operator +(Point a, Point b) =>
        new Point(a.X + b.X, a.Y + b.Y);
}

var bag = new Bag();
Console.WriteLine(bag[1]); // 香蕉

var p1 = new Point(1, 2);
var p2 = new Point(3, 4);
var sum = p1 + p2;
Console.WriteLine($"({sum.X}, {sum.Y})"); // (4, 6)

五、C# 14 的 field 关键字

过去要校验赋值时,属性得手写私有字段。C# 14 引入 field 关键字代表编译器生成的幕后字段,省去声明:

namespace CSharpDemo;

class Message
{
    public string Text
    {
        get;
        set => field = value ?? throw new ArgumentNullException(nameof(value));
    }
}

var m = new Message { Text = "hi" };
Console.WriteLine(m.Text);

这里的 set 用表达式体配合 field,既简洁又做了空检查。如果类型里恰好也有个叫 field 的标识符,用 @fieldthis.field 区分即可。

Tip

field 是 C# 14 新特性,旧版本编译器不认。写兼容老项目的代码时,仍用手动私有字段的写法。

六、什么时候别用

表达式体不是越多越好。两个反例:

第一个:逻辑一长串还硬挤成一行,可读性反而更差。超过一屏或一个表达式装不下,就用普通方法体。

第二个:带副作用的复杂操作。比如表达式体里塞进多个方法调用和分支,读者很难一眼看清。简单、纯计算、一眼能懂的才适合。

来看一个反例——把多步逻辑硬塞进表达式体:

namespace CSharpDemo;

// 不推荐:一行塞太多,读了才知在干嘛
int Score(string s) =>
    s.Length > 0 ? (s[0] == 'A' ? 10 : 5) + (s.Contains('x') ? 3 : 0) : 0;

这种写法编译器能过,但人读起来要拆半天才懂。一旦逻辑超过「一个清晰的计算」,就退回普通方法体,把步骤拆开。

Note

表达式体只是写法更短,不提升性能,也不改变语义。团队风格统一比「能写多短」更重要。

七、与 C# 12 主构造器、记录的搭配

C# 12 的主构造器(primary constructor)和记录(record)天然适合表达式体。比如给一个记录加个计算属性:

namespace CSharpDemo;

record Point(int X, int Y)
{
    public double DistanceFromOrigin => Math.Sqrt(X * X + Y * Y);
}

var p = new Point(3, 4);
Console.WriteLine(p.DistanceFromOrigin); // 5

主构造器把参数直接变成员,DistanceFromOrigin 再用表达式体算了一步,整段非常紧凑。表达式体在「数据载体 + 少量派生属性」这种类型里尤其好用。

Tip

记录本就强调「值」与「不可变」,配合只读的表达式体属性,能写出既短又安全的类型。需要可变状态时再用普通 class。

八、与其它写法的对比

表达式体 vs 普通方法体:两者编译结果相同,区别只在可读性。经验法则——「一句话能说清」的用 =>;需要多步、需要 if/循环、需要 try 的,用普通体。

表达式体 vs Lambda:别搞混。成员上的 => 是表达式体成员(成员定义的一部分);方法体里 x => x * 2 才是 Lambda(一个值)。两者都用 => 符号,但语境不同。

新手常混淆的另一点是:表达式体成员「没有自己的作用域」。它背后就是那个成员的方法体,所以里面用的变量(如 field、其他成员)和写普通方法体时完全一样,并不会因为写成了 => 就多一层闭包。把它当成普通体的「单行简写」最不容易想错,也最不容易写出意外捕获。

九、最佳实践

  • 只读属性、简单计算属性优先用表达式体。
  • 单行 return 的方法改成表达式体,主流程更清爽。
  • 构造器里「只赋一个字段」可用表达式体;多步初始化还是用普通体。
  • 运算符、索引器这类「返回一个值」的成员很适合。
  • 一行塞不下或带复杂分支时,果断退回普通方法体,别逞强。

十、循序渐进:从普通体到表达式体

初学时可以先全部写普通方法体,等熟悉了再「翻译成」表达式体。两者语义完全相同,没有谁更高级。一个判断标准:读这行代码时,你能不能在半秒内说出「它返回/做了什么」?能,就用 =>;犹豫,就退回大括号。

想象点奶茶:普通体是「打开菜单—选口味—确认下单」三步;表达式体是「报一个招牌组合」一步到位。熟客用一步,新手用三步都行,店员(编译器)最后都一样做出来。表达式体只是让你写顺手之后更省事,绝不是硬指标。

十一、小结

=> 适用于「一句话就能说清」的成员:只读属性、简单方法、构造器赋值、索引器和运算符。它减少样板代码,但别为了短而牺牲清晰。记住:语法糖的甜,建立在读得懂的前提上。C# 14 的 field 关键字进一步让带校验的属性也能写得很短,配合 C# 12 的主构造器/记录更是相得益彰。