面向对象:有 C++ 基础,刚入门 C# 的工程师
目标:看到 C# 代码时,一眼识别哪些是语法糖,知道该不该用、为什么用
一、什么是 C# 语法糖?为什么 C++ 程序员容易“看懵”
C# 的很多写法并不是“黑魔法”,而是 编译器层面的语法糖:
- ✔ 提高可读性
- ✔ 减少样板代码
- ✔ 编译期即可展开为等价逻辑
但对 C++ 程序员来说,问题在于:
- C# 语法糖密度极高
- 很多写法 默认就是推荐写法
- 不懂“糖的本质”,就容易对代码失去控制感
二、最核心、天天都会见到的语法糖(必须掌握)
1. var —— 编译期类型推断(不是动态)
var list = new List<int>();
- 类型在编译期已确定
- ≠
dynamic
C++ 对照
| C++ | C# |
|---|---|
| auto | var |
工程建议
- 右侧类型清晰 → 推荐用
- 公共 API / 字段 → 不用
2. 表达式体成员 =>
int Add(int a, int b) => a + b;
public int Count => _items.Count;
- 常用于小函数 / 属性
- 极大减少样板代码
3. 字符串插值 $""
var msg = $"X={x}, Y={y}";
- 可读性远好于
string.Format - 类似 C++ 的
fmt::format
4. Null 处理三件套:?. / ?? / ??=
obj?.Method();
value ?? defaultValue;
value ??= 10;
| 写法 | 含义 |
|---|---|
?. |
null 则不调用 |
?? |
null 则取右值 |
??= |
null 才赋值 |
三、现代 C# 的高频高级语法糖
5. switch 表达式(非常重要)
var result = x switch
{
< 0 => "neg",
0 => "zero",
> 0 => "pos",
_ => "unknown"
};
优势
- 有返回值
- 编译器检查分支是否穷尽
对比 C++
- 远强于传统
switch-case
6. 模式匹配(Pattern Matching)
if (obj is Person { Age: > 18 } p)
{
Console.WriteLine(p.Name);
}
常见写法:
x is null
x is not null
x is int i
7. 解构(Deconstruction)
var (x, y) = GetPoint();
- tuple / record 默认支持
- 类似 C++ 的 structured binding
8. record + with(数据模型神器)
public record User(string Name, int Age);
var u2 = u1 with { Age = 30 };
自动获得:
- 值相等
- ToString
- 解构
- 复制修改
四、集合与数据处理相关语法糖
9. 集合初始化器
var list = new List<int> { 1, 2, 3 };
var dict = new Dictionary<int, string>
{
[1] = "A",
[2] = "B"
};
10. LINQ(语法糖 + 扩展方法)
var result = data
.Where(x => x > 0)
.Select(x => x * 2)
.ToList();
必须理解
- 延迟执行
ToList()是执行点- 可读性 ≠ 无性能代价
11. 索引 & 范围
var last = arr[^1];
var slice = arr[1..^1];
五、委托 / Lambda / 事件相关语法糖
12. Lambda 表达式
x => x * x
13. Func / Action
Func<int, int> f = x => x * 2;
Action<string> log = s => Console.WriteLine(s);
14. 事件订阅 +=
button.Click += OnClick;
button.Click -= OnClick;
⚠ 注意:不是运算符重载
本质是事件的 add/remove 访问器
六、对象构造与初始化语法糖
15. 对象初始化器
var p = new Person
{
Name = "Tom",
Age = 18
};
16. init / required
class Config
{
public required string Path { get; init; }
}
init:仅初始化期可写required:不赋值直接编译错误
七、异步相关语法糖(核心)
17. async / await
await Task.Delay(1000);
- 编译器生成状态机
- 非阻塞
18. await foreach(异步流)
await foreach (var item in stream)
{
}
八、容易误解但必须认识的语法糖
19. 顶级语句(Top-level statements)
Console.WriteLine("Hello");
- 编译器自动生成
Main
20. global using
// 没写 using System;
// 但 Console 可直接用
九、C++ → C# 语法糖速查表
| C++ | C# |
|---|---|
| auto | var |
| lambda | lambda |
| std::function | Func / Action |
| struct + == | record |
| nullptr | null / nullable |
| if(ptr) | ?. ?? |
| switch-case | switch 表达式 |
| initializer_list | 集合初始化器 |
| coroutine | async / await |
| structured binding | 解构 |
十、工程级使用建议(很重要)
✅ 推荐大胆使用
- var
?./??- switch 表达式
- record
- LINQ
- async / await
⚠️ 谨慎使用
- 过深的 LINQ 链
- 复杂嵌套模式匹配
- 隐式 lambda 捕获
❌ 不推荐滥用
- dynamic
- 过度反射
结语
C# 的语法糖不是“偷懒”,而是把正确的工程实践变成默认选项。
当你理解了这些糖的本质,再回头看 C# 项目代码,
你会发现:
“原来它并不乱,只是我还没适应这种表达方式。”