C# 也能像 Python 一样写脚本 | .NET 10 构建基于文件的应用
什么是基于文件的应用
在单个文件中编写代码,并且能够运行。在这方面 python 是课代表。如今 C# 也能做到了。在 .NET 10 中,微软引入了基于文件的应用(File-based Apps)的概念,允许开发者在单个 .cs 文件中编写、运行和构建应用程序。这种方式极大地简化了开发流程,特别适合于快速原型设计、脚本编写和小型工具的开发。
环境要求
得安装 .NET 10 SDK 才能使用基于文件的应用功能。可以通过下面的命令来检查 .net 版本:
| dotnet --version |
这里应该显示 10.0.0 或更高版本。
上示例
示例1: date-checker.cs 使用标准库的应用
| var targetDate = DateTime.Now; | |
| Console.WriteLine("当前时间是: " + targetDate); | |
| Console.WriteLine("当前日期是今年的第 {0} 天", targetDate.DayOfYear); |
示例2: sales-data-analyse.cs 依赖第三方库的应用
| using CsvHelper; | |
| using System.Text.Json; | |
| using System.Globalization; | |
| var json = await File.ReadAllTextAsync("sales_data.json"); | |
| var sales = JsonSerializer.Deserialize<List<SaleRecord>>(json); | |
| var topProducts = sales.GroupBy(s => s.Product) | |
| .Select(g => new | |
| { | |
| Product = g.Key, | |
| TotalAmount = g.Sum(s => s.Amount) | |
| }) | |
| .OrderByDescending(g => g.TotalAmount) | |
| .Take(10) | |
| .ToList(); | |
| using var writer = new StreamWriter("top_products.csv"); | |
| using var csv = new CsvWriter(writer, CultureInfo.InvariantCulture); | |
| csv.WriteRecords(topProducts); | |
| Console.WriteLine("报告生成成功"); | |
| record SaleRecord(string Product, decimal Amount, DateTime Date); |
分别使用下面的命令运行这两个示例:
| dotnet run .\date-checker.cs | |
| dotnet run .\sales-data-analyse.cs |
指令#:的用法介绍
要去使用 #: 开头的指令来配置包、sdk、编译选项。
使用 #:sdk 指令来选择 SDK
默认的SDK是 Microsoft.NET.Sdk,如果需要使用 Microsoft.NET.Sdk.Web 来构建 web 应用,可以使用下面的指令:
使用 #:package 指令来引入第三方库
上面代码使用@指定版本号,三个版本分别表示使用指定版本、最新版本和指定主版本的最新库。
使用 #:property 指令设置编译选项
编译属性就是 csproj 文件中的属性,可以使用 #:property 指令来设置:
使用 #:reference 指令来引用本地程序集
使用 #:project 指令来引用本地项目
CLI 支持
下面是一些支持基于文件的应用的 CLI 命令:
dotnet run <file.cs>:运行指定的.cs文件。dotnet build <file.cs>:构建指定的.cs文件。dotnet publish <file.cs>:发布指定的.cs文件。dotnet pack <file.cs>:打包指定的.cs文件。dotnet project convert <file.cs>:转换指定的.cs文件为一个完整的项目。dotnet restore <file.cs>:还原指定的.cs文件中引用的包。dotnet clean <file.cs>:清理指定的.cs文件生成的输出。dotnet run <file.cs> -- <args>:运行指定的.cs文件,并传递额外的命令行参数。
文章中的实验代码,请参考 https://github.com/denglei1024/dotnet-file-based-apps。
参考引用:
- File-based apps
- Exploring C# File-based Apps in .NET 10
- C# File-based Apps in .NET 10: Run and Build Apps from a Single .cs File
如果这篇文章对你有帮助,欢迎点赞、在看、转发给更多 .NET 开发者 ❤️
2026-05-06 14:14:23【出处】:https://www.cnblogs.com/denglei1024/p/19979190
=======================================================================================
.NET 10 File-Based Apps:一个 .cs 文件搞定一切,C# 终于也能像 Python 一样写脚本了!
引言:告别 .csproj,C# 也能"单文件即运行"
还记得用 Python 写脚本时的那种爽快感吗?一个 .py 文件,直接 python hello.py 就能跑。而 C# 开发者呢?哪怕只是想写个"Hello World",也得先 dotnet new console 生成一堆项目文件,然后才能编译运行。
这种"仪式感",在 .NET 10 中终于成为历史。
.NET 10 引入了一个重磅新特性——File-Based Apps(文件级应用)。它允许你仅用一个 .cs 文件,无需任何 .csproj 项目文件,就能直接编译、运行、甚至发布为独立可执行文件。C# 从此真正具备了脚本语言的开发体验,同时保留了编译型语言的性能优势。
一、什么是 File-Based Apps?
File-Based Apps 是 .NET 10 SDK 引入的一项创新功能,允许开发者从单个 C# 源文件构建、运行和发布 .NET 应用程序,无需创建传统的项目文件(.csproj)。
.NET SDK 会自动根据源文件顶部的 #: 指令生成必要的项目配置,为脚本、工具和小型应用提供了一种轻量级的替代方案。
核心优势
| 特性 | 说明 |
|---|---|
| 零配置 | 无需 .csproj 文件,一个 .cs 文件即可运行 |
| 自包含 | 配置内嵌在源文件中,文件即项目 |
| Native AOT 默认启用 | 发布时自动生成本地 Ahead-of-Time 编译的可执行文件 |
| 自动打包为 .NET 工具 | 支持 dotnet pack 直接打包为全局工具 |
| 平滑升级 | 可随时通过 dotnet project convert 转换为完整项目 |
二、环境准备
要使用 File-Based Apps,你需要:
- .NET 10 SDK 或更高版本
- 任意文本编辑器(VS Code、Cursor、记事本均可)
- C# 扩展(推荐,用于 IntelliSense 支持)
验证 SDK 版本:
dotnet --version
# 输出应为 10.0 或更高
三、快速上手:5 分钟写出第一个 File-Based App
3.1 最简单的 Hello World
创建一个文件 hello.cs:
Console.WriteLine("Hello, File-Based App!");
直接运行:
dotnet run hello.cs
或者使用更简洁的语法:
dotnet hello.cs
没错,就这么简单!没有 dotnet new,没有 .csproj,一个文件直接跑。
3.2 引用 NuGet 包:#:package 指令
File-Based Apps 使用 #: 前缀的指令来配置构建。最常用的就是 #:package,用于引用 NuGet 包。
创建一个 sqlite-demo.cs:
#:package Microsoft.Data.SQLite@8.0.0
using Microsoft.Data.Sqlite;
var connectionString = "Data Source=:memory:";
using var connection = new SqliteConnection(connectionString);
connection.Open();
var command = connection.CreateCommand();
command.CommandText = "CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT);" +
"INSERT INTO users (name) VALUES ('山友');" +
"SELECT * FROM users;";
using var reader = command.ExecuteReader();
while (reader.Read())
{
Console.WriteLine($"ID: {reader.GetInt32(0)}, Name: {reader.GetString(1)}");
}
运行:
dotnet run sqlite-demo.cs
输出:
ID: 1, Name: 山友
版本控制技巧:
#:package Newtonsoft.Json— 省略版本号(需配合 Central Package Management)#:package Serilog@3.1.1— 指定精确版本#:package Spectre.Console@*— 使用最新版本
3.3 指定 SDK:#:sdk 指令
默认使用 Microsoft.NET.Sdk,但你可以轻松切换为 Web SDK 或 Aspire SDK:
#:sdk Microsoft.NET.Sdk.Web
#:package Swashbuckle.AspNetCore
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.MapGet("/", () => "Hello from File-Based Web App!");
app.MapGet("/api/health", () => new { status = "ok", timestamp = DateTime.UtcNow });
app.Run();
运行:
dotnet run webapi.cs
使用
Microsoft.NET.Sdk.Web时,会自动包含同目录下的*.json配置文件(如appsettings.json)。
3.4 设置 MSBuild 属性:#:property 指令
#:property TargetFramework=net10.0
#:property PublishAot=false
#:property LogLevel=$([MSBuild]::ValueOrDefault('$(LOG_LEVEL)', 'Information'))
Console.WriteLine($"Current Log Level: {Environment.GetEnvironmentVariable("LOG_LEVEL") ?? "Information"}");
#:property支持完整的 MSBuild 属性表达式,包括环境变量读取、条件表达式等。
3.5 引用其他项目:#:project 指令
#:project ../SharedLibrary/SharedLibrary.csproj
using SharedLibrary;
Console.WriteLine(Helper.GetMessage());
四、完整的 CLI 命令支持
File-Based Apps 并非"玩具功能",它拥有完整的 CLI 支持:
运行应用
# 标准方式
dotnet run --file app.cs
# 简写(推荐)
dotnet run app.cs
# 更简写(当目录无 .csproj 时)
dotnet app.cs
# 传递参数
dotnet run app.cs -- arg1 arg2
# 从标准输入管道执行
echo 'Console.WriteLine("hello from stdin!");' | dotnet run -
构建与清理
# 编译
dotnet build app.cs
# 清理构建产物
dotnet clean app.cs
# 清理所有 file-based apps 缓存
dotnet clean file-based-apps
发布与打包
# 发布(默认启用 Native AOT,生成独立可执行文件)
dotnet publish app.cs
# 打包为 .NET 全局工具
dotnet pack app.cs
# 转换为传统项目(平滑升级路径)
dotnet project convert app.cs
依赖恢复
# 显式恢复 NuGet 包
dotnet restore app.cs
# 构建时自动恢复(默认行为)
dotnet build app.cs
五、Native AOT:默认开启的高性能发布
File-Based Apps 的一个杀手锏特性是默认启用 Native AOT 发布。这意味着:
- ✅ 更快的启动速度 — 无需 JIT 编译预热
- ✅ 更小的内存占用 — 无运行时依赖
- ✅ 独立可执行文件 — 单文件分发,无需 .NET Runtime
如果你不需要 AOT(例如依赖反射较多的场景),可以关闭:
#:property PublishAot=false
六、用户机密(User Secrets)
File-Based Apps 支持用户机密管理,基于文件路径的哈希生成稳定的 Secrets ID:
# 设置机密
dotnet user-secrets set "ApiKey" "your-secret-value" --file app.cs
# 查看机密
dotnet user-secrets list --file app.cs
七、Unix 系统上的 Shebang 支持
在 Linux/macOS 上,你可以让 .cs 文件像 Shell 脚本一样直接执行:
#!/usr/bin/env dotnet
#:package Spectre.Console
using Spectre.Console;
AnsiConsole.MarkupLine("[green]Hello, World![/]");
赋予执行权限并运行:
chmod +x app.cs
./app.cs
⚠️ 注意:使用 Shebang 时,文件必须使用
LF换行符,不能包含 BOM。
八、Launch Profile 配置
File-Based Apps 支持启动配置,使用 [应用名].run.json 文件:
// app.run.json
{
"profiles": {
"http": {
"commandName": "Project",
"launchBrowser": true,
"applicationUrl": "http://localhost:5000",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"https": {
"commandName": "Project",
"launchBrowser": true,
"applicationUrl": "https://localhost:5001;http://localhost:5000",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}
运行指定 Profile:
dotnet run app.cs --launch-profile https
九、目录组织最佳实践
File-Based Apps 会继承父目录的 Directory.Build.props、Directory.Packages.props 等隐式构建文件。为了避免冲突:
❌ 不推荐
📁 MyProject/
├── MyProject.csproj
├── Program.cs
└──📁 scripts/
└── utility.cs // 会受到 MyProject.csproj 的隐式文件影响
✅ 推荐
📁 MyProject/
├── MyProject.csproj
└── Program.cs
📁 scripts/
└── utility.cs // 独立目录,避免干扰
十、实战场景:File-Based Apps 能做什么?
场景 1:快速原型验证
#:package Newtonsoft.Json
using Newtonsoft.Json;
var data = new { Name = "File-Based App", Version = "1.0", Features = new[] { "Fast", "Simple", "Powerful" } };
Console.WriteLine(JsonConvert.SerializeObject(data, Formatting.Indented));
场景 2:CLI 工具脚本
#!/usr/bin/env dotnet
#:package Spectre.Console
#:package System.CommandLine
using Spectre.Console;
using System.CommandLine;
// 构建一个功能完整的 CLI 工具
var rootCommand = new RootCommand("文件批量重命名工具");
var patternOption = new Option<string>("--pattern", "匹配模式");
rootCommand.AddOption(patternOption);
rootCommand.SetHandler((string pattern) =>
{
AnsiConsole.MarkupLine($"[blue]正在处理匹配模式: {pattern}[/]");
// 业务逻辑...
}, patternOption);
await rootCommand.InvokeAsync(args);
场景 3:数据迁移/ETL 脚本
#:package Dapper
#:package Microsoft.Data.SqlClient
#:package CsvHelper
using Dapper;
using Microsoft.Data.SqlClient;
using CsvHelper;
using System.Globalization;
// 从数据库读取,写入 CSV — 一个文件搞定数据迁移
场景 4:定时任务/自动化脚本
#:package Quartz
// 使用 Quartz 构建定时任务,部署为单文件后台服务
十一、File-Based Apps vs 传统 .csproj 项目
| 对比维度 | File-Based Apps | 传统 .csproj 项目 |
|---|---|---|
| 项目文件 | ❌ 不需要 | ✅ 需要 |
| 适合场景 | 脚本、工具、原型、小型应用 | 中大型应用、团队协作 |
| 启动速度 | ⚡ 更快(AOT 默认) | 🔄 标准 JIT |
| 依赖管理 | #: 指令内嵌 |
PackageReference |
| 测试支持 | ❌ 不支持 dotnet test |
✅ 完整支持 |
| 团队规模 | 个人/小团队 | 任意规模 |
| 升级路径 | dotnet project convert |
本身就是完整项目 |
关键洞察:File-Based Apps 不是替代传统项目,而是填补空白——在那些"为了写个脚本还得建个项目"的场景下,它提供了恰到好处的轻量方案。
十二、从 File-Based App 到完整项目
当你的脚本逐渐复杂,需要单元测试、CI/CD 或多项目结构时,File-Based Apps 提供了平滑的升级路径:
dotnet project convert app.cs
执行后,SDK 会:
- 复制
.cs文件到以应用名命名的目录 - 根据
#:指令生成等效的.csproj文件 - 保留原始文件不变
十三、写在最后
.NET 10 的 File-Based Apps 是一个看似小巧、实则意义深远的特性。它标志着 .NET 平台在开发体验上的一次重要进化:
- 对初学者:降低了 C# 的入门门槛,一个文件就能开始编程
- 对脚本开发者:C# 终于可以像 Python 一样写脚本,同时享受编译型语言的性能
- 对运维/DevOps:单文件可执行,部署极简,Native AOT 带来极致启动速度
- 对原型开发:快速验证想法,需要时再平滑升级为完整项目
C# 不再是"重型企业级开发"的专属标签,它也能轻盈、敏捷、即刻运行。
参考资源
- .NET 官方文档 - File-based apps
- GitHub - awesome-dotnet-fba — 精选 .NET 10 File-Based Apps 代码示例集
- .NET 10 File Based Apps Demonstration
2026-07-08 10:33:05【出处】:https://www.cnblogs.com/shanyou/p/21227428
=======================================================================================
如果,您希望更容易地发现我的新博客,不妨点击一下绿色通道的【关注我】。(●'◡'●)
因为,我的写作热情也离不开您的肯定与支持,感谢您的阅读,我是【Jack_孟】!
本文来自博客园,作者:jack_Meng,转载请注明原文链接:https://www.cnblogs.com/mq0036/p/19979714
【免责声明】本文来自源于网络,如涉及版权或侵权问题,请及时联系我们,我们将第一时间删除或更改!
浙公网安备 33010602011771号