Appearance
第 2 章:运行第一个示例
本章目标
- 跑通主案例
- 确认生成器真的在工作
- 学会去哪里看生成出来的代码
先看现象
这章不只看“运行命令”,还要把运行现象和源码位置对上。
主案例在仓库中的目录是:
sample/01-tostring-generator
这个目录下有一个示例工程 ToStringGenerator.Sample。当它运行时,你会看到 Person、Employee、Container<string> 这些类型都打印出了 ToString() 结果。
重点是:这些类型里很多都没有手写 ToString()。
再看代码
程序入口在:
sample/01-tostring-generator/ToStringGenerator.Sample/Program.cs
先看最关键的一段:
csharp
var person = new Person
{
Name = "张三",
Age = 30
};
Console.WriteLine(person.ToString());这段代码的重点不是 Console.WriteLine,而是 Person 明明没有手写 ToString(),这里却能直接调用。
建议直接在仓库根目录执行:
powershell
dotnet run --project .\sample\01-tostring-generator\ToStringGenerator.Sample\ToStringGenerator.Sample.csproj如果一切正常,你会看到类似下面的输出:
text
Person { Name = 张三, Age = 30 }
Employee { Name = 李四, Department = 技术部, EmployeeId = 1001, Salary = 15000.50 }
...你现在先不用逐字对照输出内容,只要抓住一个事实:编译后的程序确实调用到了生成器补出来的方法。
去哪里看生成的代码
很多新手以为生成器既然“生成了代码”,就应该在项目源文件目录里多出一个 .cs 文件。通常不是这样。
优先去看:
sample/01-tostring-generator/ToStringGenerator.Sample/obj/Debug/net8.0/generated
这是构建过程中的中间产物目录,很多生成文件会出现在这里。
例如 Person.g.cs 的核心内容大致是:
csharp
public partial class Person
{
public override string ToString()
{
return $"Person {{ Name = {Name?.ToString() ?? "null"}, Age = {Age} }}";
}
}把它和 SimpleClass.cs 对起来看,你就能明白“编译阶段额外补代码”到底是什么意思。
如果你用的是 IDE,也可以尝试在项目树里看:
AnalyzersGenerated Files
如何验证
按下面顺序做:
- 打开
sample/01-tostring-generator/ToStringGenerator.Sample/Program.cs - 执行
dotnet run --project .\sample\01-tostring-generator\ToStringGenerator.Sample\ToStringGenerator.Sample.csproj - 去
obj/.../generated目录找生成出来的.g.cs - 随便打开一个,比如
Person.g.cs,确认里面真的有ToString()
如果你能完成这四步,这一章就算真正过了。
如果你还缺“整张源码地图”,直接跳去看 源码导读。
常见误解
- 误解 1:看不到生成文件,说明生成器没生效
- 不一定,先看
obj或 IDE 的生成文件节点
- 不一定,先看
- 误解 2:只要项目能运行,就说明生成器配置完全正确
- 也不一定,最好亲自去看生成文件
- 误解 3:输出结果和手写代码没区别,就没必要学源生成器
- 恰恰相反,重点就在于“效果相同,但维护方式完全不同”
本章新名词
obj- Generated Files
- Analyzer 引用
本章小结
这一章最重要的是建立直觉:编译后真正参与运行的代码,比你手写的更多。
下一章我们就来解释,这个案例为什么要拆成三个工程,以及它们是怎么协作的。
上一章 | 返回主教程目录 | 下一章:理解三工程结构