Chapter 1. Introducing C# and .NET

覆盖C#设计保证、CLR/BCL/runtime分层、版本历史与C# 10/.NET 6能力矩阵,建立语言、API、运行时和部署证据。

学习目标

  • 能比较Object Orientation、Type Safety、Memory Management与Platform Support各自保证和不保证的内容
  • 能绘制C#、compiler、CLR、BCL、runtime、TFM与application model分层,定位feature failure属于哪层
  • 能设计C# 10/.NET 6兼容矩阵,用compile、publish和target-machine运行证据验证升级

为什么第一章先拆开Language与Platform

C#不是“.NET的另一个名字”。C#定义source syntax、type rules和semantics;compiler把source生成IL/metadata或其他target artifact;CLR负责load、verify、JIT与GC;BCL提供string、collections、I/O等APIs;ASP.NET Core、desktop与MAUI等application models再建立更高层约定。排错若把这些混在一起,就会把“编译器不认识syntax”“reference assembly无API”“目标机缺runtime”都叫成C#版本问题。

先预测:项目设置LangVersion 10就能调用所有.NET 6 API吗;GC会及时关闭socket吗;type-safe表示绝不发生InvalidCastException吗;IL相同就能在所有OS运行吗;self-contained publish不再依赖native platform吗。答案都是否。

Object Orientation

C#以class/struct、encapsulation、inheritance、interface和runtime polymorphism支持对象建模。Virtual/interface call根据runtime type dispatch;static type决定可见members与overload resolution。Object orientation帮助把state与invariants收拢到owner,但可变alias、deep inheritance和hidden side effects仍需设计约束,不会因用了class自动消失。

IFormatter formatter = new JsonFormatter();
string payload = formatter.Format(order); // runtime dispatch
 
// Overload selection仍以compile-time types为基础。
Print((object)order);

Composition通常比继承更容易限定lifetime与替换。Interface contract要说明thread safety、nullability、exception和resource ownership;否则“面向对象”只提供syntax。测试同时覆盖compile-time overload与runtime dispatch,防止把二者混成同一机制。

Type Safety

Type Safety让compiler和CLR限制不兼容operation:每个expression有type,conversion、generic constraint和member access在明确规则下发生。它减少memory corruption与shape guessing,但并不表示运行时永不失败。Explicit cast、array covariance、dynamic、reflection和interop都可能把检查推迟,nullable warning也依赖项目开启与annotation质量。

object value = "42";
string text = (string)value;       // checked at runtime
int number = int.Parse(text);      // type-safe, but input may be invalid
 
// dynamic/reflection/interop把部分检查推迟到运行时。

“编译通过”只证明static rules成立,不证明input valid、API available或invariant正确。Boundary tests应覆盖invalid cast、null、dynamic binder、serialization与native marshaling;domain constructors再把合法业务状态收窄。

Memory Management

Managed object由GC根据reachability回收,程序通常不手工free。GC roots包括static、stack/reference、handle等;reachable不等于仍有业务价值,event subscription、timer和cache可造成managed leak。GC也不管理文件句柄、socket、transaction等稀缺resource的及时释放,它们依赖IDisposable/await using与owner lifetime。

Platform Support

C#/.NET支持多OS与architectures,因为managed IL由目标runtime执行,BCL提供跨平台contract。但platform-neutral不是platform-identical:filesystem casing/path、timezone、globalization、native library、COM、Windows Event Log和UI stack都可能不同。Target Framework Moniker决定compile-time API surface,Runtime Identifier影响publish assets,OS guards表达运行时条件。

 

Cross-platform验收在target OS/RID真正运行,不只在开发机编译。Path、encoding、culture、line endings、TLS和native dependency进入matrix;platform-specific capability放在adapter后,并用OperatingSystem.IsWindows()等guard和analyzer attribute约束调用。

分步1 / 3

切换object、type-safe、managed与portable

CLRs, BCLs, and Runtimes

CLR是Common Language Runtime:load assemblies、validate metadata、JIT methods、manage exceptions/threads/GC。BCL是Base Class Library contracts和implementations。Runtime distribution把CLR、BCL和host组合成可部署产品;reference assemblies则供compiler决定可调用API,不是运行时implementation。

同一C# compiler可用新syntax target旧TFM,只要lowering不需要缺失runtime/API;反之旧syntax也可调用新BCL。Feature analysis必须写四列:syntax first version、compiler lowering、BCL dependency、runtime/JIT behavior。比如file-scoped namespace主要是source transformation,而某个新API需要net6 reference和target runtime。

分步1 / 3

切换language、runtime、library与app model

A Brief History of C#

C#从早期object-oriented/type-safe managed language,逐步加入generics、nullable values、iterators、LINQ/lambdas、dynamic、async/await、pattern matching、nullable references、records与top-level/global namespace conveniences。历史意义不在背年份,而在理解feature如何叠加:LINQ依赖generics/delegates/lambdas/extensions,async依赖Task/awaiter protocol,records依赖已有type/equality机制。

版本历史还提醒兼容性:compiler、language和runtime发布节奏可分离;某feature只有syntax变化,某feature需要runtime recognition或BCL types。Legacy project升级时先锁定当前 TFM/LangVersion/SDK,再逐项迁移,不让IDE默认升级掩盖生产约束。

What's New in C# 10

C# 10的代表能力包括global using、file-scoped namespace、record structs、struct parameterless constructors与field initializers、extended property patterns、lambda improvements、CallerArgumentExpression、constant interpolated strings等。它们分属ceremony reduction、data modeling、pattern/API diagnostics,不能用“现代语法”一概而论。

迁移要按observable semantics检查。Global using会改变name lookup/ambiguity;record struct值语义与copy成本不同于record class;lambda inference可能影响overload;CallerArgumentExpression是diagnostic text,不是可信identity。每项都用compile fixtures和API contract tests确认。

分步1 / 3

切换C# 10、.NET 6、older target与deployment

Upgrade and deployment gate

Repository应通过global.json或CI image锁定SDK,项目显式设置TargetFramework/LangVersion/Nullable。Package restore lock与runtimeconfig纳入artifact;部署选择framework-dependent或self-contained,并记录size、patching和roll-forward tradeoff。多target library需要为每个TFM编译,不能只测最高版本。

升级验收包括source/ABI/API compatibility、serialization schema、reflection behavior、culture/platform和performance。若只在IDE“能运行”,没有目标机runtime/RID evidence,就未完成平台迁移。

本章回顾:每个Feature都有四个版本坐标

  1. C#提供object orientation与type rules,但不自动保证domain invariant或无runtime failure。
  2. GC管理managed memory reachability,IDisposable管理external resource lifetime。
  3. CLR、BCL、runtime distribution和application model有不同职责。
  4. Cross-platform需要验证OS/RID/native差异,不等于相同artifact无条件运行。
  5. C# 10 feature通过LangVersion、TFM、runtime和deployment matrix验收。

练习

问题 1:为什么LangVersion=10仍可能无法编译某段示例?

问题 2:怎样证明一个library真正cross-platform?

问题 3:GC与Dispose的测试证据有什么不同?

术语表

名词解释

本章出现的专业名词,用大白话再讲一遍。

language-platform boundary
type-safety envelope
managed-resource split
runtime distribution
feature compatibility matrix

资料与写作方式声明

本章以C# 10 in a Nutshell, Chapter 1: Introducing C# and .NET权威目录界定学习范围,并结合正文列出的技术资料独立重写;不宣称复现原书正文,也不沿用原作表述。

原作版权归作者与出版社所有;本站原创教学结构与表述仅供学习交流。

讨论

评论区加载中…