mcpField
D
dotnet-version-detection

dotnet-version-detection

github.com/wshaddix开发8672 次安装35 周前更新
代码仓库

关于 dotnet-version-detection

从项目文件检测 .NET 版本信息,并根据解析出的目标框架和 SDK 提供指导。该技能设计为其他 .NET 开发技能运行前的步骤,按优先级读取配置,并检查语言版本和预览设置。

主要功能

  1. 01从项目文件解析目标框架
  2. 02使用 global.json 和 SDK 作为回退
  3. 03检查 C# 语言与预览设置
  4. 04提示目标框架和 SDK 不匹配
  5. 05按项目缓存检测结果

适用场景

  1. 01为现有 .NET 项目选择适用指导
  2. 02检查 SDK 与目标框架是否一致
  3. 03识别 C# 或预览功能设置

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/wshaddix/dotnet-skills --skill dotnet-version-detection

安装后在 Claude Code 中输入/dotnet-version-detection确认已加载。

详细介绍

dotnet-version-detection

从项目文件中检测 .NET 版本信息,并提供针对特定版本的指导。在进行任何 .NET 开发工作之前,必须首先运行此技能。所有其他技能都依赖检测到的版本来调整其指导。

这是一项横切技能,由 [skill:dotnet-advisor] 和几乎所有专业技能引用。另请参阅 [skill:dotnet-file-based-apps],了解可在没有 .csproj 的情况下运行的 .NET 10+ 文件型应用。


检测优先级算法

严格按照以下顺序读取项目文件。**编号越大的来源,优先级越低。**确定 TFM 后,即停止继续检查低优先级来源。

1. .csproj 中直接声明的 <TargetFramework>(最高优先级)

读取距离当前工作文件/目录最近的 .csproj 文件。

<PropertyGroup>
  <TargetFramework>net10.0</TargetFramework>
</PropertyGroup>

如果找到,且值是字面量 TFM(例如 net10.0,而非 $(SomeProperty)),则该值为权威 TFM。报告该值,然后继续进行其他检测(步骤 5)。

如果值是 MSBuild 属性表达式(以 $( 开头),则跳转到步骤 4处理未解析的属性。

2. .csproj 中的 <TargetFrameworks>(多目标框架)
<PropertyGroup>
  <TargetFrameworks>net8.0;net10.0</TargetFrameworks>
</PropertyGroup>

如果找到:

  • 报告所有 TFM(以分号分隔)
  • 根据最高版本的 TFM 提供指导(例如 net10.0)
  • 提示较低版本的 TFM 可能需要 polyfill:“考虑使用 [skill:dotnet-multi-targeting],通过 PolySharp/Polyfill 将语言功能移植到 net8.0”
  • 继续进行其他检测(步骤 5)
3. Directory.Build.props 中的共享 TFM

如果在 .csproj 中未找到 <TargetFramework> 或 <TargetFrameworks>(或者 .csproj 继承了共享属性文件),则读取当前目录或任一父目录(直到解决方案根目录)中的 Directory.Build.props。


<PropertyGroup>
  <TargetFramework>net10.0</TargetFramework>
</PropertyGroup>

如果找到,则使用其中的 TFM。注意:项目级 .csproj 值优先于 Directory.Build.props。

4. MSBuild 属性表达式(带警告的回退)

如果 TFM 值是 MSBuild 属性表达式而非字面量:

<TargetFramework>$(MyCustomTfm)</TargetFramework>

发出警告:

警告:无法解析 MSBuild 属性 $(MyCustomTfm)。 无法静态确定 TFM。将回退到 global.json 中的 SDK 版本。

然后回退到 global.json SDK 版本(步骤 4a),或 dotnet --version(步骤 4b)。

4a. global.json SDK 版本
{
  "sdk": {
    "version": "10.0.100"
  }
}

将 SDK 版本映射为近似 TFM:

  • 8.0.xxx -> net8.0
  • 9.0.xxx -> net9.0
  • 10.0.xxx -> net10.0
  • 11.0.xxx-preview.x -> net11.0

报告:“根据 global.json SDK 版本推断 TFM。请在项目文件中确认实际 TFM。”

4b. dotnet --version(最后手段)

如果不存在 global.json,则使用 dotnet --version 的输出推断 SDK 版本。映射方式同 4a。

报告:“根据已安装的 SDK 版本推断 TFM。未找到 global.json 或 .csproj。建议使用 dotnet new 创建项目。”


其他检测(步骤 5)

确定 TFM 后,还需检查以下文件以获取补充版本信息。无论通过哪个优先级步骤确定 TFM,都必须执行这些检查。

5a. global.json SDK 版本

即使 TFM 是从 .csproj 中确定的,也要读取 global.json 中的:

  • sdk.version —— 固定的 SDK 版本
  • sdk.rollForward —— rollForward 策略(例如 latestFeature、latestPatch)

同时报告 SDK 版本和 TFM。若两者不一致,则发出警告:

警告:TFM 为 net10.0,但 global.json 固定使用 SDK 9.0.100。 项目的目标框架比固定使用的 SDK 更新。请更新 global.json,或确认构建环境中安装了正确的 SDK。

5b. C# 语言版本

检查 .csproj 或 Directory.Build.props 中是否显式指定了 <LangVersion>:

<LangVersion>preview</LangVersion>
  • 如果为 preview,则报告“已启用 C# 预览功能。这会解锁已安装 SDK 中可用的下一个 C# 版本(例如,使用 .NET 11 预览版 SDK 时可启用 C# 15 预览功能)。”
  • 如果为 latest,则报告检测到的 TFM 对应的默认 C# 版本
  • 如果为显式版本(例如 12.0),则报告该版本;如果它低于 TFM 对应的默认版本,则发出警告
  • 如果未指定,则使用该 TFM 对应的默认 C# 版本(参见下方参考数据)
5c. 预览功能检测

检查 .csproj 或 Directory.Build.props 中是否包含以下属性:

EnablePreviewFeatures:

<EnablePreviewFeatures>true</EnablePreviewFeatures>

报告:“已启用 .NET 预览功能。可使用预览版 API 和类型。”

Runtime-async 功能标志(.NET 11+):

<Features>$(Features);runtime-async=on</Features>

报告:“已启用 Runtime-async。Async/await 使用运行时级执行,而非编译器状态机。”

注意:Runtime-async 还需要 <EnablePreviewFeatures>true</EnablePreviewFeatures>。

5d. 多目标详细信息

如果检测到多目标(步骤 2),还需注明:

  • 哪些 TFM 属于 LTS、STS 或 Preview
  • 哪些 TFM 即将结束支持
  • 建议使用 [skill:dotnet-multi-targeting] 获取 polyfill 指导

结构化输出格式

检测完成后,按以下结构化格式呈现结果:

.NET Version Detection Results
==============================
TFM:              net10.0 (or net8.0;net10.0 for multi-targeting)
Highest TFM:      net10.0
C# Version:       14 (default for net10.0)
SDK Version:      10.0.100 (from global.json)
Preview Features: none
Runtime-Async:    not enabled
Warnings:         none

Guidance: This project targets .NET 10 LTS with C# 14. Use modern patterns
including field-backed properties, collection expressions, and primary
constructors. All guidance will target net10.0 capabilities.

对于多目标:

.NET Version Detection Results
==============================
TFMs:             net8.0;net10.0
Highest TFM:      net10.0
C# Version:       14 (default for highest TFM)
SDK Version:      10.0.100 (from global.json)
Preview Features: none
Warnings:         net8.0 reaches end of support Nov 2026

Guidance: Multi-targeting net8.0 and net10.0. Guide on net10.0 patterns.
For net8.0 compatibility, use PolySharp/Polyfill for language features.
See [skill:dotnet-multi-targeting] for detailed polyfill guidance.

边缘情况

未找到 .csproj

如果工作区中不存在 .csproj:

  • 检查 .sln 或 .slnx 文件,查找其中引用的项目
  • 如果未找到项目文件,继续执行回退链:
    1. 读取 global.json 中的 SDK 版本(步骤 4a),并据此推断 TFM
    2. 如果没有 global.json,使用 dotnet --version(步骤 4b)推断 TFM
    3. 仅当这两种推断方法都失败时,提示:“未检测到 .NET 项目或 SDK。默认按 net10.0(当前 LTS)提供指导。使用 dotnet new 创建项目。”
MSBuild 属性间接引用

如果 <TargetFramework> 包含 $(PropertyName):

  • 输出:“未解析的属性:$(PropertyName)。 无法通过静态分析确定 TFM。”
  • 回退至 global.json 中的 SDK 版本,然后使用 dotnet --version
  • 建议通过 dotnet --list-sdks 或 dotnet msbuild -getProperty:TargetFramework 验证 TFM
文件不一致

如果 .csproj 声明 net10.0,但 global.json 固定使用 SDK 9.0.100:

  • 优先采用 .csproj 中的 TFM(优先级更高)
  • 提示存在不匹配
  • 建议更新 global.json 以保持一致
未安装 SDK

如果 dotnet --version 执行失败或找不到命令:

  • 报告:“此系统未检测到 .NET SDK。请从 https://dot.net 安装。”
  • 如果存在项目文件,仍报告其中的 TFM
  • 说明未安装 SDK 将导致构建失败
.fsproj 和 .vbproj

相同的检测逻辑也适用于 F#(.fsproj)和 VB.NET(.vbproj)项目。所有 .NET 项目类型中的 <TargetFramework> 元素都相同。


缓存行为

版本检测结果应按项目缓存(以 .csproj 路径区分)。在以下情况下重新检测:

  • 用户切换到解决方案中的其他项目
  • 用户明确要求重新检测
  • .csproj、Directory.Build.props 或 global.json 文件被修改

版本到功能参考数据

最后更新:2026-02-11

此参考数据将 .NET 版本映射到其 C# 语言版本、关键功能和支持生命周期。本节与上述检测逻辑分开——检测逻辑确定当前使用的版本;此数据则将该版本映射到可用功能。

版本矩阵
.NET 版本状态C# 版本TFM支持结束时间备注
.NET 8LTS(支持中)C# 12net8.02026 年 11 月即将结束支持
.NET 9STSC# 13net9.02026 年 5 月即将结束支持
.NET 10LTS(当前)C# 14net10.02028 年 11 月新项目推荐使用
.NET 11Preview 1C# 15(预览版)net11.0待定(预计 STS 支持结束时间:约 2028 年 5 月,若于 2026 年 11 月正式发布)仅限预览版,不适用于生产环境
C# 版本功能亮点

C# 12 (net8.0)

  • 类和结构体的主构造函数
  • 集合表达式([1, 2, 3])
  • ref readonly 参数
  • Lambda 默认参数
  • 使用 using 为任意类型创建别名
  • 内联数组
  • 拦截器(实验性)

C# 13 (net9.0)

  • params 集合(任意集合类型)
  • Lock 类型(System.Threading.Lock)
  • 新转义序列 \e
  • 方法组自然类型改进
  • 对象初始值设定项中的隐式索引器访问
  • 迭代器和异步方法中的 ref 与 unsafe
  • 分部属性

C# 14 (net10.0)

  • 字段支持的属性(field 上下文关键字)
  • nameof 支持未绑定泛型类型
  • 扩展功能改进(扩展块)
  • 在更多上下文中将 Span<T> 作为一等类型
  • 泛型的 allows ref struct 反约束

C# 15 预览版 (net11.0)

  • 集合表达式参数(用于指定容量或比较器的 with() 语法):
    List<int> nums = [with(capacity: 32), 0, ..evens, ..odds];
    HashSet<string> names = [with(comparer: StringComparer.OrdinalIgnoreCase), "Alice"];
    
  • 随着 .NET 11 持续推出预览版,预计还会有其他功能
.NET 11 Preview 1 值得关注的功能

检测到 net11.0 TFM 且启用了预览功能时,即可使用以下功能:

  • 运行时异步:在运行时层实现 Async/await(需要 <EnablePreviewFeatures>true</EnablePreviewFeatures> + <Features>$(Features);runtime-async=on</Features>)
  • Zstandard 压缩:System.IO.Compression.Zstandard(比 Brotli/Deflate 快 2–7 倍)
  • BFloat16:面向 AI/ML 工作负载的 System.Numerics.BFloat16
  • Happy Eyeballs:用于双栈网络的 ConnectAlgorithm.Parallel
  • Android 上的 CoreCLR:MAUI Android Release 构建的默认运行时
  • XAML 源生成:MAUI 中的默认方式(取代 XAMLC)
  • EF Core:复杂类型 + 支持 TPT/TPC 继承的 JSON 列
  • WASM 上的 CoreCLR:可替代 Blazor WASM 中 Mono 的实验性方案
支持生命周期指南

报告版本信息时,请包含生命周期相关说明:

  • 即将停止支持(6 个月内):发出警告并建议使用 [skill:dotnet-version-upgrade]
  • 预览版/RC:警告“不可用于生产环境”,除非用户明确选择使用
  • STS 即将结束支持:指出其支持期限比 LTS 短
  • 当前 LTS:确认其为新项目的推荐目标版本

评论

支持 Markdown