第1章:Introducing C#
从Hello World、语法和变量到Console I/O、CIL managed execution与多种.NET实现。
学习目标
- 能实现并编译Hello World,区分source、project、assembly、CIL、JIT和process runtime evidence
- 能分析C# statements、keywords、identifiers、type definition、Main、variables与Console input/output syntax
- 能比较C# language version、target framework、.NET Framework/.NET Core/.NET Standard与runtime availability
为什么第一个程序要追到managed execution
Console.WriteLine能输出并不代表理解C#程序。source必须属于project,compiler生成assembly中的CIL与metadata,CLR加载并验证types,JIT把将执行的方法编译成当前CPU的machine code,最后process调用entry point。任何一层失败都可能表现为“程序跑不起来”,但修法完全不同。
先预测:syntax error时是否已经生成assembly;target runtime缺失时Main是否执行;.NET Standard本身能否像runtime一样启动program。把预测写成pipeline,再运行命令核对artifact和exit code。
Hello, World:source、project与command
书中从完整entry point理解C# 7.0,不把后来的top-level statements混入版本边界。一个console project含.csproj和source files;build读取target framework与compile items,run先build再启动output。
using System;
public static class Program
{
public static int Main(string[] args)
{
Console.WriteLine("Hello. My name is Inigo Montoya.");
return 0;
}
}dotnet new console --name HelloWorld
cd HelloWorld
dotnet build
dotnet run
echo $?build成功证据包括output assembly、0 exit code与明确target;run成功还需预期stdout。若只在IDE点击Run,不知道实际project、configuration和runtime,CI failure就难以复现。
↡描述source files、target framework、references与build properties的编译输入集合。Compilation and Execution Pipeline
C# compiler先做lexing/parsing、name binding与type checking,再生成CIL和metadata。CIL是stack-based intermediate instructions,不是CPU直接执行的native binary;metadata描述types、members和references。CLR loader解析assembly,JIT按需把methods编译为machine code。
逐阶段检查source到process
Program.cs + .csproj
-> C# compiler
-> HelloWorld.dll: CIL + metadata + manifest
-> CLR loader/type verification
-> JIT native code
-> process stdout + exit codeC# Syntax Fundamentals
statement通常以semicolon结束,block用braces形成scope。keywords有语言定义含义,不能直接作identifier;identifier区分大小写并受命名规则约束。whitespace多数用于分隔token和提高可读性,不改变block结构。
class是type definition,method是class member。Main是传统console entry point;其return type和parameters必须符合允许形式。C#在compile time检查name与type,因此string count = 42;不会等到runtime才报错。
切换statement、variable、Main与invalid identifier
public sealed class Greeter
{
public static string CreateMessage(string name)
{
return $"Hello, {name}!";
}
}compiler diagnostics是结构证据,不要只看“红线”。记录error code、file、line和message;修复第一个root error后再build,后续可能是parser cascade。
Working with Variables
variable declaration把static type与identifier引入scope;assignment把兼容value存入variable。未赋值local不能读取,compiler执行definite-assignment analysis。field有default value,但依赖隐式default会降低intent清晰度。
string name;
name = "Ada";
int visitCount = 1;
Console.WriteLine($"{name}: {visitCount}");变量不是无约束container。第2–3章会展开numeric/string/value/reference categories;本章先建立“declaration决定可接受operations”的static typing直觉。rename还必须考虑scope和case-sensitive references。
Console Input and Output
Console.Write不自动newline,Console.WriteLine追加newline,Console.ReadLine读取一行。input是external boundary:可能为空、EOF/null或不满足目标format;不能直接假设用户输入合法integer。
Console.Write("Your name: ");
string? rawName = Console.ReadLine();
string name = string.IsNullOrWhiteSpace(rawName) ? "anonymous" : rawName.Trim();
Console.WriteLine($"Hello, {name}!");第6版时代是否启用nullable reference analysis取决于compiler/project设置;这里的?用于明确现代重跑时的null boundary,复刻C# 7.0代码时也应以显式null check表达同一runtime事实。comments解释why与constraints,不重复代码表面动作。
Debugging the Smallest Program
compile failure先读diagnostic;launch failure确认output和runtime;wrong output在Main设置breakpoint并检查variables;input hang确认程序在等待stdin。debugger能暂停、step和inspect,但不能替代可重复command和asserted output。
最小diagnostic表:source path是否属于project;configuration/target是什么;build产物在哪;运行的assembly是否最新;runtime版本是什么;stdin是什么;stdout/stderr和exit code是什么。证据齐全后才改code。
Managed Execution and CLI
Common Language Infrastructure定义CIL、metadata、Common Type System、assemblies与runtime services。C#只是产生CLI-compatible artifacts的语言之一。managed不等于“没有native code”,而是execution由runtime协调,JIT/AOT仍会产生machine code。
assembly manifest记录identity、version、files和references;metadata让reflection、type safety与cross-language tooling成为可能。garbage collection管理managed objects的memory lifetime,但file handle等external resource仍需后续章节的deterministic cleanup。
Multiple .NET Frameworks
C# language version、API target和runtime implementation不是同一个number。C# 7.0可面向.NET Framework 4.7或当时的.NET Core;.NET Standard描述library API surface,不是独立runtime。能compile只证明target reference assemblies可用,能run还要求compatible runtime implementation。
切换Framework、Core、Standard与missing runtime
本章回顾:从一行输出建立完整运行模型
- project contract决定source、target与references。
- compiler将C#生成assembly中的CIL、metadata和manifest。
- CLR加载managed code,JIT为当前platform生成native method code。
- syntax、variables和Console I/O分别有compile与runtime failure boundary。
- C# language、target framework、.NET implementation与runtime availability必须分开记录。
练习
问题 1:dotnet build成功但dotnet run失败,应按什么顺序检查?
问题 2:syntax error、runtime missing与wrong output分别属于pipeline哪一层?
问题 3:为什么.NET Standard不是另一个可直接启动的runtime?
术语表
名词解释
本章出现的专业名词,用大白话再讲一遍。
- managed execution
- project contract
- Common Intermediate Language
- entry-point signature
- console boundary