Expression Bodied Members 什么时候能用
只有方法、属性、索引器、构造函数、析构函数、运算符重载这些成员的实现体是单条表达式(不是语句块)时,才能用
=>。比如
return x + y;可以,但
{ Console.WriteLine("hi"); return x; } 不行——里面含语句,必须用传统大括号写法。
编译器会把
=>形式自动转成等效的传统语法,不带来运行时开销,纯属语法糖。
方法和只读属性怎么写最安全
方法用
=>最常见于无副作用、计算型逻辑;只读属性(
get)也适合,但要注意:返回值不能是
void,也不能带
async(除非返回
Task或
Task<t></t>,且需配合
async关键字)。
public int Square(int x) => x * x;
public string Name => _name ?? "unknown";
public Task<string> GetDataAsync() => _httpClient.GetStringAsync(url);</string>(注意:这行本身不加
async,因为右边已是
Task) 错误写法:
public void Log() => Console.WriteLine("x"); —— void不支持表达式体,必须用
{}
构造函数和索引器的限制很实际
构造函数可用
=>,但只能用于委托给另一个构造函数(
this(...)或
base(...)),不能包含任意逻辑。索引器同理,
get和
set各自独立支持,但
set的右侧必须是表达式,不能写
value = ...这种赋值语句。
public Person(string name) : this(name, 0) => {};(合法,空体仅作语法占位)
public string this[int i] => _items[i];(只读索引器)
public string this[int i] { get => _items[i]; set => _items[i] = value; }(注意:右边是 _items[i] = value表达式,不是语句) 错误写法:
set => { _items[i] = value; }; —— 大括号块不被允许
别在 async 方法里漏掉 async/await
很多人以为
async Task<t> Foo() => await Something();</t>能成立,其实不行:表达式体里不能直接用
await,因为
await是语句级操作。正确写法是保留
async关键字,并用大括号包裹
await语句,或者让右侧直接返回一个已有的
Task。 ✅ 正确:
public async Task<int> GetCountAsync() { return await _db.CountAsync(); }</int>
✅ 正确:public Task<int> GetCountAsync() => _db.CountAsync();</int>(不 await,直接转发 Task) ❌ 错误:
public async Task<int> GetCountAsync() => await _db.CountAsync();</int>(编译失败)
这个点最容易在迁移旧代码时忽略,尤其当团队习惯统一加
async前缀时,容易误以为表达式体也能套用相同模式。
