自定义类型支持解构必须手动实现 public void deconstruct(out t1 p1, out t2 p2, …) 实例方法,参数顺序严格对应解构变量顺序,且每个 out 参数必须赋值;元组天生支持解构但按位置匹配,不触发逻辑;记录类型默认提供 deconstruct。

自定义类型要支持 var (x, y) = obj 这种解构语法,必须手动实现 Deconstruct 方法;不实现就直接用会编译报错,不是语言自动推导出来的。
Deconstruct 方法必须满足哪些签名要求
编译器只认一种签名:public 实例方法、返回 void、所有参数都是 out 类型,且顺序严格对应解构变量顺序。
- 方法名必须是
Deconstruct,大小写敏感,不能加static或async -
out参数类型需与你要解构出的变量类型一致,比如想解出string和int,就得写out string name, out int age - 每个
out参数在方法体内必须被赋值一次,否则编译失败(哪怕只是name = default;) - 结构体调用时会复制值,所以
Deconstruct里修改字段不影响原实例;类则作用于引用对象本身
元组解构和自定义类型解构的区别
元组(如 (string, int))天生支持解构,不需要你写 Deconstruct;但它的类型推导完全依赖位置和元素类型,不看名字。
- 命名元组如
(Name: "Alice", Age: 30),解构时仍按位置匹配:var (n, a) = person;中n拿到的是Name字段值,不是因为叫Name,而是因为它在第一个位置 - 自定义类解构则完全由你控制——你可以让
Deconstruct返回FirstName和BirthYear,即使类里字段叫firstName和dob - 元组解构不触发任何逻辑,纯数据搬运;
Deconstruct是普通方法,可以包含计算、转换、甚至抛异常(虽然不推荐)
和模式匹配(is / switch)一起用要注意什么
Deconstruct 本身不参与模式匹配;但解构后的变量可以进后续判断,比如 if (obj is { Name: "Alice", Age: >18 }) —— 这里用的是属性模式,不是解构。
- 想在
switch表达式里同时解构+判断,得组合写:obj switch { Person p when p.Age > 18 => ... },再对p解构,不能一步到位 - 记录(
record)类型默认带Deconstruct,参数顺序就是构造函数参数顺序;但如果你重写了构造函数或加了私有字段,记得同步更新Deconstruct - 丢弃符
_在解构中合法:var (_, age) = person;,但Deconstruct方法里仍需给第一个out参数赋值,不能跳过
最容易忽略的是:解构变量的作用域仅限当前语句块,且 Deconstruct 的参数顺序一旦定下,所有调用都按这个顺序绑定——改顺序等于破坏 ABI 兼容性,老代码会悄悄拿错值。











