浏览知识库目录

C#

环境、SDK 与项目基线

确认 SDK、Runtime 与目标框架,建立采用 SLNX、多项目和统一编译属性的跨平台项目基线。

环境、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.jsonbuild 编译项目引用图;test 运行测试项目。需要可重复的 CI 时,先显式还原,再对后续命令使用 --no-restore


八、常见错误

机器有 .NET 10,项目仍然无法构建

先在项目目录运行 dotnet --versionglobal.json 可能要求一个未安装的功能带,或者当前 shell 找到了另一套 dotnet

binobj 提交到版本库

它们是可再生构建产物,应加入忽略规则。源文件、项目文件、锁定策略和必要配置模板才是输入。

只在 IDE 中验证

IDE 最终也调用 SDK。发布前必须从项目根目录执行 CLI 构建,避免依赖某位开发者的 IDE 缓存和隐式设置。

用预览 SDK 编译正式基线

并行安装预览版没有问题,但本系列必须由 global.json 和 CI 固定在 10.0.302,不启用 preview 语言版本。


九、练习与自测

练习:

  1. 创建上述四个项目,用 dotnet sln list 检查成员。
  2. 故意让 Infrastructure 引用 Cli,观察为何形成错误的依赖方向,再删除引用。
  3. 在一个可空字符串上直接调用 Length,观察编译器警告并用显式校验修复。
  4. 从子目录运行 dotnet --version,确认仍能找到根目录 global.json

自测:

  • SDK、Runtime 和 net10.0 分别约束什么?
  • global.json 为什么不是运行时版本声明?
  • 文件式应用何时合适,何时应创建项目?
  • Directory.Build.props 会影响哪些子项目?

十、官方资料

上一篇:C# 完整学习路线 | 下一篇:语法、类型系统与内存语义