C#
环境、SDK 与项目基线
确认 SDK、Runtime 与目标框架,建立采用 SLNX、多项目和统一编译属性的跨平台项目基线。
发布于 2026年7月23日
环境、SDK 与项目基线
本篇建立整个系列共用的开发环境。目标不是罗列安装界面,而是弄清楚“当前使用哪个 SDK 编译、程序依赖哪个运行时、目标框架允许调用哪些 API,以及解决方案如何组织多个项目”。
一、学习目标
- 区分 .NET SDK、Runtime、C# 编译器与目标框架
- 在 Windows、Linux、macOS 上确认实际环境
- 理解 SDK 的并行安装和选择规则
- 创建
StudyTasks.slnx与三个源码项目 - 建立可空引用、隐式 using 和警告策略
- 区分文件式应用与正式项目
前置条件:能使用终端,并理解绝对路径、相对路径和进程退出码。
二、SDK、Runtime 与目标框架
SDK 用来还原、编译、测试、打包和发布;Runtime 负责运行已经构建的应用。安装 SDK 会同时安装相应 Runtime,但只安装 Runtime 的机器不能构建源码。
dotnet --version
dotnet --list-sdks
dotnet --list-runtimes
dotnet --info
三种版本不要混为一谈:
- SDK 版本示例:
10.0.302 - Runtime 补丁版本示例:
10.0.10 - 目标框架:
net10.0
项目目标是 net10.0,表示编译时使用 .NET 10 的参考程序集。运行框架依赖部署时,目标机器还需要兼容的 .NET 10 Runtime。
三、确认实际使用的 SDK
dotnet --version 会从当前目录向父目录寻找 global.json。如果存在,它会参与选择 SDK;因此同一台机器在不同目录执行命令可能得到不同版本。
创建版本基线:
mkdir StudyTasks
cd StudyTasks
dotnet new globaljson --sdk-version 10.0.302 --roll-forward disable
disable 让本系列和验证容器精确使用 10.0.302。团队应把 global.json 提交到版本库,并让 CI 使用相同 SDK;升级补丁时显式修改它并重跑完整验证。
Windows 可以用 where.exe dotnet,Linux/macOS 可以用 command -v dotnet 查看启动器路径。真正的完整状态仍以 dotnet --info 为准。
四、文件式应用的边界
.NET 10 可以直接运行单个 C# 文件:
// hello.cs
Console.WriteLine($"运行时:{Environment.Version}");
dotnet run hello.cs
文件式应用适合实验 API、复现缺陷和短小自动化,但贯穿项目需要多个程序集、测试、分析规则和打包元数据,因此使用项目文件。不要把一次性文件不断扩张成隐含依赖的大型程序。
五、创建解决方案和项目
dotnet new sln -n StudyTasks
dotnet new install xunit.v3.templates::3.2.2
dotnet new classlib -n StudyTasks.Core -o src/StudyTasks.Core -f net10.0
dotnet new classlib -n StudyTasks.Infrastructure -o src/StudyTasks.Infrastructure -f net10.0
dotnet new console -n StudyTasks.Cli -o src/StudyTasks.Cli -f net10.0
dotnet new xunit3 -n StudyTasks.Tests -o tests/StudyTasks.Tests -f net10.0
dotnet sln add src/StudyTasks.Core/StudyTasks.Core.csproj
dotnet sln add src/StudyTasks.Infrastructure/StudyTasks.Infrastructure.csproj
dotnet sln add src/StudyTasks.Cli/StudyTasks.Cli.csproj
dotnet sln add tests/StudyTasks.Tests/StudyTasks.Tests.csproj
.NET 10 的 dotnet new sln 默认生成 StudyTasks.slnx。SLNX 是 XML 格式,但日常仍通过 dotnet sln 管理,不要手工复制项目条目。
建立项目引用:
dotnet add src/StudyTasks.Infrastructure reference src/StudyTasks.Core
dotnet add src/StudyTasks.Cli reference src/StudyTasks.Core
dotnet add src/StudyTasks.Cli reference src/StudyTasks.Infrastructure
dotnet add tests/StudyTasks.Tests reference src/StudyTasks.Core
dotnet add tests/StudyTasks.Tests reference src/StudyTasks.Infrastructure
六、统一编译基线
在根目录创建 Directory.Build.props:
<Project>
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<AnalysisLevel>latest-recommended</AnalysisLevel>
<LangVersion>14.0</LangVersion>
</PropertyGroup>
</Project>
Nullable 让编译器分析引用是否可能为 null;它不会在运行时阻止外部 JSON 返回空值。TreatWarningsAsErrors 适合保持新项目干净,但升级 SDK 前要在独立分支检查新增分析规则。
显式写 LangVersion 是为了声明本系列基线。一般产品项目也可以让 SDK 按目标框架选择默认稳定语言版本,避免把更高语言版本与较旧运行时组合得过于随意。
七、第一个可运行入口
编辑 src/StudyTasks.Cli/Program.cs:
using System.Runtime.InteropServices;
Console.WriteLine("StudyTasks 已就绪");
Console.WriteLine($"Framework: {RuntimeInformation.FrameworkDescription}");
Console.WriteLine($"OS: {RuntimeInformation.OSDescription}");
运行:
dotnet run --project src/StudyTasks.Cli
构建整个解决方案:
dotnet restore
dotnet build --no-restore
dotnet test --no-build
restore 解析 NuGet 依赖并生成 obj/project.assets.json;build 编译项目引用图;test 运行测试项目。需要可重复的 CI 时,先显式还原,再对后续命令使用 --no-restore。
八、常见错误
机器有 .NET 10,项目仍然无法构建
先在项目目录运行 dotnet --version。global.json 可能要求一个未安装的功能带,或者当前 shell 找到了另一套 dotnet。
把 bin 和 obj 提交到版本库
它们是可再生构建产物,应加入忽略规则。源文件、项目文件、锁定策略和必要配置模板才是输入。
只在 IDE 中验证
IDE 最终也调用 SDK。发布前必须从项目根目录执行 CLI 构建,避免依赖某位开发者的 IDE 缓存和隐式设置。
用预览 SDK 编译正式基线
并行安装预览版没有问题,但本系列必须由 global.json 和 CI 固定在 10.0.302,不启用 preview 语言版本。
九、练习与自测
练习:
- 创建上述四个项目,用
dotnet sln list检查成员。 - 故意让
Infrastructure引用Cli,观察为何形成错误的依赖方向,再删除引用。 - 在一个可空字符串上直接调用
Length,观察编译器警告并用显式校验修复。 - 从子目录运行
dotnet --version,确认仍能找到根目录global.json。
自测:
- SDK、Runtime 和
net10.0分别约束什么? global.json为什么不是运行时版本声明?- 文件式应用何时合适,何时应创建项目?
Directory.Build.props会影响哪些子项目?
十、官方资料
上一篇:C# 完整学习路线 | 下一篇:语法、类型系统与内存语义