news 2026/9/20 11:49:24

免建项目直接运行 C:.NET 10 文件式应用(File-Based C Apps)完整实战指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
免建项目直接运行 C:.NET 10 文件式应用(File-Based C Apps)完整实战指南

免建项目直接运行 C#:.NET 10 文件式应用(File-Based C# Apps)完整实战指南

【免费下载链接】skillsRepository for skills to assist AI coding agents with .NET and C#项目地址: https://gitcode.com/GitHub_Trending/skills17/skills

文件式 C# 应用(File-Based C# Apps)是 .NET 10 SDK 引入的能力,允许直接用dotnet hello.cs运行一个.cs文件,无需dotnet new console创建任何项目。本文基于当前仓库dotnet-advanced插件中的csharp-scriptsSkill(见 SKILL.md),完整讲解该能力的适用场景、#:指令系统、Unix shebang、AOT 下的 JSON 序列化方案、项目转换与旧版 SDK 降级路径,并辅以仓库评测用例与源码佐证,帮助你在语言实验、原型验证和小工具开发中彻底摆脱项目脚手架。

一、这个 Skill 解决什么问题

csharp-scripts是仓库 dotnet-advanced 插件下的四个高级技能之一(其余为dotnet-pinvokenuget-trusted-publishingvectorization),定位是"针对小众场景的进阶 .NET/C# 技能"。它的核心主张是:当用户明确想要 C#/.NET 代码、但又不想创建项目时,用文件式应用来运行代码

适用场景(When to Use)

  • 快速验证某个 C# 概念、API 或语言特性,用一个文件式应用跑通即可;
  • 在大项目里集成之前,先原型验证一段逻辑;
  • 用一个入口文件加几个辅助.cs文件拼装一个小工具。

不适用场景(When Not to Use)

  • 用户要的是与语言无关的临时脚本、一次性计算,或 Shell/Python/PowerShell 风格的自动化;
  • 用户需要完整项目、解决方案集成,或在现有应用中添加项目引用;
  • 用户正工作在某个已存在的 .NET 解决方案中,想把代码加进去;
  • 应用已经大到需要把项目结构、构建定制、测试或发布配置放进.csproj

一句话判断标准:代码量适合"文件"而非"项目"时用文件式应用;一旦需要构建定制、测试或发布配置,就应该迁移到.csproj

唯一输入

输入必填说明
C# 代码或意图要运行的代码,或对文件式应用功能的描述

仓库证据:Skill 如何被评测

仓库在 tests/dotnet-advanced/csharp-scripts/eval.yaml 中为这个 Skill 提供了能力评测(type: capability)。评测刺激词是"测试 C# 语言特性":询问 C# 是否支持创建stackallocSpan<nint>(native-sized 整数)。评测器断言:

  • 命令以成功退出(exit-success);
  • 输出匹配(nint|nuint|native)
  • 输出包含stackalloc
  • 输出不匹配dotnet new console—— 即 Agent 必须走dotnet <file>.cs文件式路径,而不是退化为建项目;
  • 评分标准明确写着:"使用dotnet <file>.cs(文件式应用)运行测试,而不是用dotnet new console创建完整项目"。

这个评测用例从侧面印证了本 Skill 的设计意图:文件式应用不是"没项目时的临时凑合",而是被正式约定为 C# 语言实验的标准执行方式。

二、环境前提:SDK 版本与 Feature Band

文件式应用对 SDK 版本有硬性要求,开始前先执行:

dotnet --version

判读规则:

  • 文件式应用要求 .NET 10 或更高版本
  • #:include#:exclude以及跨文件的传递式(transitive)指令处理要求 SDK 10.0.300 或更高
  • SDK 10.0.100 / 10.0.200 构建可以运行单文件应用,但不支持上述多文件指令;
  • 版本低于 10 时,走本文第八节的"旧版 SDK 降级方案"。

注意这里要区分"运行时版本"和"SDK 功能带(feature band)":dotnet --version输出的完整版本号(如10.0.300)中,第二段300就是功能带,它决定了指令能力的边界。一个 10.0.200 的 SDK 依然是 .NET 10,但拿不到多文件指令。

作为环境参考:当前仓库根目录的 global.json 将 SDK 固定为11.0.100-previewrollForward: latestMajor),高于 10.0.300 门槛,因此在该仓库环境中文件式应用的全部指令均可用。

三、最小工作流:写文件 → 运行 → 传参 → 清理

1. 写应用文件

创建一个使用顶级语句(top-level statements)的入口.cs文件,并放在任何现有项目目录之外,避免与.csproj冲突:

#!/usr/bin/env dotnet // hello.cs Console.WriteLine("Hello from a file-based app!"); var numbers = new[] { 1, 2, 3, 4, 5 }; Console.WriteLine($"Sum: {numbers.Sum()}");

文件组织规范:

  • 使用顶级语句,不要Main方法、类或命名空间的样板代码;
  • using指令放在文件顶部(如果有 shebang 行和#:指令,则放在它们之后);
  • 类型声明(类、record、enum)放在所有顶级语句之后。

2. 运行

dotnet hello.cs

SDK 会自动完成构建并运行,且结果会被缓存,后续重复运行很快。需要传参时,在--之后传入:

dotnet hello.cs -- arg1 arg2 "multi word arg"

3. 清理

会话结束后删除应用文件;如需清掉缓存的构建产物:

dotnet clean hello.cs

四、指令系统:#:开头的声明式配置

指令必须放在文件顶部(可选的 shebang 行之后),且必须在任何using指令或其他 C# 代码之前。所有指令都以#:开头。下面逐一说明六类指令。

#:package— NuGet 包引用

除非应用有意使用集中包管理(CPM),否则必须指定版本;当接受最新可用版本时用@*(接受预发布版则用@*-*):

#:package Humanizer@2.14.1 using Humanizer; Console.WriteLine("hello world".Titleize());

#:property— MSBuild 属性

语法为#:property PropertyName=Value,可在文件内设置任意 MSBuild 属性:

#:property AllowUnsafeBlocks=true #:property PublishAot=false #:property NoWarn=CS0162

MSBuild 表达式与属性函数同样受支持,例如:

#:property LogLevel=$([MSBuild]::ValueOrDefault('$(LOG_LEVEL)', 'Information'))

常用属性速查:

属性用途
AllowUnsafeBlocks=true启用unsafe代码
PublishAot=false关闭原生 AOT(默认开启)
NoWarn=CS0162;CS0219抑制特定警告
LangVersion=preview启用预览语言特性
InvariantGlobalization=false启用文化相关的全球化行为

#:project— 项目引用

按相对路径引用另一个项目:

#:project ../MyLibrary/MyLibrary.csproj

#:ref— 文件式应用间的引用

当某个.cs文件应当编译进独立的程序集(而不是与入口文件同属一个编译单元)时,用#:ref建立类似"项目引用"的边界;普通的辅助文件共享同一程序集,应该用#:include

#:property ExperimentalFileBasedProgramEnableRefDirective=true #:ref ../Shared/Formatter.cs Console.WriteLine(Formatter.Title("hello world"));

使用要点:

  • 被引用的文件会作为自己的虚拟项目编译,并作为项目引用加入;
  • 如果被引用文件是没有顶级语句的库,需要在那个文件里加#:property OutputType=Library
  • 引用方要消费的成员应为publicinternal成员跨程序集不可见;
  • #:ref是传递式的:被引用文件里可以再包含自己的#:ref及其他#:指令;
  • 相对路径按包含该指令的文件所在位置解析;
  • 部分 SDK 构建需要#:property ExperimentalFileBasedProgramEnableRefDirective=true;如果当前 SDK 不带该属性也接受#:ref,可以移除这行。

#:sdk— SDK 选择

覆盖默认的Microsoft.NET.Sdk,例如切换到 Web SDK:

#:sdk Microsoft.NET.Sdk.Web

#:include#:exclude— 多文件应用

仅 .NET SDK 10.0.300 及以后支持。用#:include把辅助源文件和受支持的资源纳入同一个虚拟项目,用#:exclude从 include 模式或默认条目集中剔除文件:

#!/usr/bin/env dotnet #:include Helpers.cs #:include Models/*.cs #:exclude Models/Generated/*.cs Console.WriteLine(Formatter.Title("hello world"));

使用要点:

  • 传给dotnet的那个文件是入口点,顶级语句写在那里;
  • 类、record、enum 等声明放在被 include 的.cs文件中;
  • 优先使用显式 glob(如Helpers.csModels/*.cs),避免宽泛的递归 glob;
  • 路径按包含指令的文件所在目录解析;
  • 非入口 C# 文件中的 include 指令同样会被处理:辅助文件可以声明自己的#:package#:property#:sdk#:project#:ref#:include#:exclude
  • 除非指令类型明确支持重复,避免跨文件重复声明指令——重复的#:package#:property#:sdk#:include#:exclude会导致失败;
  • 使用#:include时,在 Unix 系系统上给入口文件加 shebang(#!/usr/bin/env dotnet)以明确入口点;shebang 文件要求LF行尾且无 BOM。

一个典型的多文件布局:

scratch/ hello.cs Helpers.cs Models/ Person.cs
#!/usr/bin/env dotnet // hello.cs #:include Helpers.cs #:include Models/*.cs var person = new Person("Ada"); Console.WriteLine(Formatter.Title(person.Name));
// Helpers.cs static class Formatter { public static string Title(string value) => value.ToUpperInvariant(); }
// Models/Person.cs record Person(string Name);

五、Unix shebang:让.cs文件直接可执行

在 Unix 平台上,三步即可让.cs文件成为可执行文件:

  1. 文件第一行加 shebang:

    #!/usr/bin/env dotnet Console.WriteLine("I'm executable!");
  2. 设置执行权限:

    chmod +x hello.cs
  3. 直接运行:

    ./hello.cs

注意:shebang 文件必须使用LF行尾(不要CRLF);该指令在 Windows 上会被忽略。

六、AOT 默认开启:用源码生成 JSON 绕过反射限制

文件式应用默认启用原生 AOT。在 AOT 下,JsonSerializer.Serialize<T>(value)这类基于反射的 API 会在运行时失败,因此必须改用源码生成(source generation)的序列化:

using System.Text.Json; using System.Text.Json.Serialization; var person = new Person("Alice", 30); var json = JsonSerializer.Serialize(person, AppJsonContext.Default.Person); Console.WriteLine(json); var deserialized = JsonSerializer.Deserialize(json, AppJsonContext.Default.Person); Console.WriteLine($"Name: {deserialized!.Name}, Age: {deserialized.Age}"); record Person(string Name, int Age); [JsonSerializable(typeof(Person))] partial class AppJsonContext : JsonSerializerContext;

要点:定义一个继承JsonSerializerContextpartial类,用[JsonSerializable]声明需要序列化的类型,然后通过AppJsonContext.Default.Person拿到强类型的JsonTypeInfo<Person>传给序列化 API。这正好与仓库另一个 Skill(system-text-json-net11)所强调的"优先强类型JsonTypeInfo<T>"方向一致。如果明确不需要 AOT,也可以通过#:property PublishAot=false关闭它(见第四节属性表)。

七、升级为完整项目:dotnet project convert

当文件式应用长到需要项目结构、构建定制、测试或发布配置时,一条命令即可原地转换:

dotnet project convert hello.cs

转换后即可获得完整的.csproj项目,进入常规的dotnet rundotnet builddotnet testdotnet publish工作流。

八、.NET 9 及更早版本的降级方案

如果 SDK 版本低于 10,文件式应用不可用。此时改用临时控制台项目:

mkdir -p /tmp/csharp-file-based-app && cd /tmp/csharp-file-based-app dotnet new console -o . --force

用应用内容替换生成的Program.cs,然后用dotnet run运行;需要 NuGet 包时用dotnet add package <name>添加;用完删除该目录。

九、验证清单(Validation)

每次使用完文件式应用工作流,对照以下清单自查:

  • dotnet --version报告 10.0 或更高(否则走降级路径);
  • 如果应用使用了#:include#:exclude或来自被包含文件的传递式指令,dotnet --version报告 SDK 10.0.300 或更高;
  • 应用无错误编译(可用dotnet build <file>.cs显式检查);
  • dotnet <file>.cs输出符合预期;
  • 多文件应用包含所有必需的辅助文件,并排除了意外匹配的文件;
  • 会话结束后应用文件和缓存产物已清理。

十、常见坑位速查表(Common Pitfalls)

坑位解决方案
.cs文件位于含有.csproj的目录中把应用移到项目目录之外,或使用dotnet run --file file.cs
#:package未指定版本指定版本:#:package PackageName@1.2.3,或用@*取最新
#:property语法错误使用PropertyName=Value=两侧无空格、不加引号:#:property AllowUnsafeBlocks=true
指令放在了 C# 代码之后所有#:指令必须紧跟可选 shebang 行之后,且在任何using指令或其他 C# 语句之前
辅助文件没有被编译在入口文件加#:include Helper.cs或合适的 glob
共享文件需要程序集边界#:ref Shared.cs而不是#:include Shared.cs;被引用文件若无入口点则加#:property OutputType=Library
宽泛的 include 引入了无关文件优先窄 include 模式,并用#:exclude排除生成文件、备份或实验文件
包含文件间出现重复指令入口点与被包含 C# 文件中的 package、property、SDK、include、exclude 指令保持全局唯一
反射式 JSON 序列化失败改用带JsonSerializerContext的源码生成 JSON(见第六节)
出现意外的构建行为或版本错误文件式应用会继承父目录的global.jsonDirectory.Build.propsDirectory.Build.targetsnuget.config;若继承设置产生冲突,把应用移到隔离目录

十一、把 Skill 用对的验证方式

综合来看,csharp-scriptsSkill 的正确使用范式可以归纳为三条主线:

  1. 能力边界先行:先确认 SDK 版本满足门槛(10.0+,多文件指令需 10.0.300+),再决定是文件式应用还是降级到临时项目;
  2. 入口文件最小化:顶级语句 + 顶部指令 + 辅助文件#:include,全部声明(类/record/enum)下沉到被包含文件;
  3. 以评测为验收标准:仓库评测(eval.yaml)明确要求通过dotnet <file>.cs运行实验代码并输出可验证的结果,而非创建dotnet new console项目——这正是本 Skill 与普通"写代码脚本"式技能的分水岭。

深入阅读可继续查看 Skill 原始定义 plugins/dotnet-advanced/skills/csharp-scripts/SKILL.md,以及插件整体定位 plugins/dotnet-advanced/README.md 和插件清单 plugins/dotnet-advanced/plugin.json。

【免费下载链接】skillsRepository for skills to assist AI coding agents with .NET and C#项目地址: https://gitcode.com/GitHub_Trending/skills17/skills

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/19 5:13:39

Linux 常用笔记

scp scp -r /data/bbt-server/service/bbt.jar root192.168.14.0:/data/bbt-server/service scp -r /data/bbt-server/service/bbt.jar root192.168.14.0:/data/bbt-server/service查询redis进程 ps aux | grep redis错误信息 /var/run/redis_6380.pid exists, process is alre…

作者头像 李华
网站建设 2026/9/20 4:39:51

机器视觉工程决策链:从打光、选型到标定的隐性知识

简介&#xff1a;本资源是一份面向高校自动化、计算机视觉及人工智能方向学习者的机器视觉基础思考题与详解文档&#xff0c;聚焦核心概念理解与工程应用认知。内容系统梳理了机器视觉的学科定位、系统组成&#xff08;图像获取、处理识别、输出控制&#xff09;、关键技术&…

作者头像 李华
网站建设 2026/9/20 10:51:49

Spring Boot 3.3与MyBatis-Plus整合实战与优化

1. 项目背景与核心价值Spring Boot 3.3.X作为当前Java生态中最主流的应用开发框架&#xff0c;其与MyBatis-Plus的组合堪称企业级开发的黄金搭档。最近在重构一个老项目时&#xff0c;我再次验证了这套技术栈的威力——原本需要200行的JDBC模板代码&#xff0c;用MyBatis-Plus只…

作者头像 李华
网站建设 2026/9/20 6:34:07

基于SpringBoot+Vue的医护人员排班管理系统设计与实践

排班问题在每个医院科室里都是月月要经历的折磨。护士长每个月末拿着纸质排班表对着住院人次和护士休假日程反复权衡&#xff0c;医生们为了换班在群里来回协调&#xff0c;最后排出来的表还是有人不满意。一个基于SpringBootVue的医护人员排班管理系统&#xff0c;就是把这些线…

作者头像 李华
网站建设 2026/9/20 5:03:08

GeoScene Pro连接人大金仓KingbaseES实操:ODBC配置与空间数据入库要点

最近在配合一个空间数据管理平台的项目时&#xff0c;客户明确要求数据底座用人大金仓 KingbaseES&#xff0c;前端负责制图、编辑和数据发布的是 GeoScene 系列&#xff0c;主力就是 GeoScene Pro。这套组合不像 ArcGIS PostgreSQL 那样开箱即用&#xff0c;资料也散&#xf…

作者头像 李华