Effective C# 第3版总复习:5章50条整书验收
以真实系统横穿语言、资源、泛型、LINQ和异常5章,按type/lifetime/execution/failure contract与全书门禁验收50条Item。
学习目标
- 能分析public SDK、data pipeline、plugin host或hot service,逐章写出50条Item相关的真实风险与证据
- 能绘制type、lifetime、execution和failure四条端到端contract chain,定位最早可阻止缺陷的边界
- 能设计outline、code、visual、compatibility和release五类整书门禁,判断是否具备发布条件
机制总览
用一个真实系统验收五十条建议
- 1
类型与替换
审计强类型边界、泛型约束和基类替换行为。
- 2
生命周期与执行
追踪 owner、Dispose、延迟枚举和 provider 边界。
- 3
失败与发布
注入异常后验证状态、清理、可观测性和回滚策略。
章级决策实验
用一个真实系统验收五十条建议
选择审计面,检查建议是否在代码、运行时和失败路径留下可重复证据。
选择推理阶段
当前阶段 · 类型与替换
审计强类型边界、泛型约束和基类替换行为。
可核验证据
编译矩阵、contract tests 与 API diff。
总复习的终点不是记住五十个标题,而是能对一个变更说明它改变了哪条契约、风险在哪里、证据是否足够。
失效—证据矩阵
用一个真实系统验收五十条建议
类型与替换
典型失效
API 表面可编译,但字符串协议和成员隐藏绕过真实契约。
核验证据
编译矩阵、contract tests 与 API diff。
生命周期与执行
典型失效
查询在资源释放后执行,或回调意外保留昂贵对象。
核验证据
heap path、枚举次数与连接日志。
失败与发布
典型失效
只测成功路径,发布后才发现部分更新和证据缺口。
核验证据
故障测试、状态快照与发布门禁记录。
为什么总复习必须审计一个完整系统
单独回答“readonly与const差别”不代表能设计跨assembly SDK;知道IQueryable延迟执行也不代表会关闭DbContext;会写exception filter也不代表系统failure后state正确。总复习把5章放进同一真实boundary,检查建议之间是否互相支持。
先预测:所有50条各举一个isolated snippet是否足以通过;同一结果在List与remote provider一致是否等于执行contract一致;catch能恢复流程是否等于strong guarantee。三个答案都是否。
↡以同一真实系统横穿5章,检查type、owner、substitution、execution和failure在boundary处是否一致。第一轮:按五章扫描同一系统
Chapter 1: Language surface
检查public values是否跨version安全、text是否有culture owner、string protocols是否转成type、callbacks/events是否声明thread与retention、hot path是否有boxing evidence、inheritance是否误用new。
Chapter 2: Lifecycle surface
画resource graph:谁创建、谁borrow、谁transfer、谁Dispose;所有constructors是否经过同一invariant;static failure能否重试;virtual activation是否在完整构造后;cache/pool是否有bound与clear policy。
Chapter 3: Substitution surface
Constraint是否最小、specialization是否同语义、ordering是否通过laws、owned T是否级联释放、variance是否由input/output位置推导、classic bridge与extension是否保持最小surface。
Chapter 4: Execution surface
每个sequence标注construction、first enumeration、terminal和repeat;IQueryable检查translation/command/round trip,iterator检查resource scope,Single/First检查0/1/many,closure检查execution-time value。
Chapter 5: Failure surface
每个public operation标注specific signal、cleanup、post-fault state、translation boundary与logging owner;用fault injection验证strong/basic guarantee,filter只做有界observation。
切换SDK、pipeline、plugin与hot service
boundary: OrderRepository.Query
owner: request scope
type: IQueryable<Order>
execution: ToListAsync at application boundary
failure: provider cause preserved; no partial domain publish第二轮:沿四条Contract Chain追踪
Type chain
从external string/DTO进入typed adapter,经generic constraint/variance,到LINQ delegate/expression binding和runtime dispatch。最早能compile-time拒绝的invalid state不应拖到provider或cast exception。
Lifetime chain
从creator与DI scope,经delegate/event、generic container、iterator capture,到materialization、Dispose/finally。每次retention和transfer都必须有owner,normal/fault/cancel paths收敛到同一released state。
Execution chain
从callback/query construction,到generic fast path与enumeration,再到terminal operator/provider command/filter search。记录次数、thread、ordering和short-circuit,禁止用source appearance猜执行。
Failure chain
从specific exception type,经cleanup与state guarantee,到filter selection、translation、retry/response和single logging boundary。Cause chain与primary fault不能被cleanup或wrapper覆盖。
↡在invalid representation、owner leak、unsupported provider node或partial mutation变成runtime事故前,最先能确定性拒绝它的位置。 ↡normal、fault、cancel和repeat路径最终到达同一valid state、released resource与可解释diagnostic的性质。切换type、lifetime、execution与failure chain
await using var session = await factory.OpenAsync(token);
var result = await session.Orders
.Where(OrderPolicies.IsReadyExpression)
.SingleAsync(order => order.Id == id, token);第三轮:整书发布门禁
- Outline:5章50条publisher titles覆盖100%,无invented unit。
- Code:每章normal、boundary与fault evidence可复现,compile/provider/ordering tests按风险运行。
- Visual:每章3个unique interactive labs解释该章state transition,不复用装饰图。
- Compatibility:base/derived、generic/classic、local/remote、C# 6/current runtime差异均有明确边界。
- Release:chapter scores、book score、MDX、type、lint在promotion前全绿。
切换outline、code、visual、compatibility与release
publisher TOC -> 7 active pages -> 21 interactive labs -> chapter 100 -> book 100 -> global gates本章回顾:50条建议最终变成四条可执行Contract
- 五章扫描确保source、lifecycle、substitution、execution与failure面无遗漏。
- Type chain把invalid state前移到compile/boundary;lifetime chain让owner和release可追踪。
- Execution chain记录真实次数、位置和ordering;failure chain保护cause、cleanup与post-fault state。
- 现代补充必须version-bounded,不能把原书历史结构改写掉。
- 整书只有在outline、code、visual、compatibility和release evidence全部通过时完成。
练习
问题 1:一个plugin返回deferred sequence并注册event,host卸载后仍无法回收,应如何跨章定位?
问题 2:怎样把一个runtime provider fault前移到earliest enforcement boundary?
问题 3:本书完成的最终证据有哪些?
术语表
名词解释
本章出现的专业名词,用大白话再讲一遍。
- whole-book audit
- earliest enforcement boundary
- path convergence
- version-bounded guidance
- release evidence chain