关于 csharp-scripts
C# Scripts 是用于运行单文件 C# 程序的技能,可快速测试语言特性、API 或原型逻辑。它介绍 .NET 10 文件应用,并为更早版本的 SDK 提供临时项目替代方案。
主要功能
- 01创建顶级语句单文件 C# 脚本
- 02用 `dotnet` 运行文件应用
- 03向脚本传递参数
- 04引用指定版本的 NuGet 包
- 05在 .NET 9 及更早版本使用临时项目
- 06将脚本转换为项目
适用场景
- 01快速测试 C# 语言特性
- 02在集成到项目之前验证逻辑
- 03无需完整项目运行小程序
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ wshaddix/ dotnet-skills --skill csharp-scripts安装后在 Claude Code 中输入/csharp-scripts确认已加载。
详细介绍
C# 脚本
适用场景
- 使用快速编写的单文件程序测试 C# 概念、API 或语言功能
- 在将逻辑集成到更大的项目之前进行原型验证
不适用场景
- 用户需要包含多个文件或项目引用的完整项目
- 用户正在现有的 .NET 解决方案中工作,并希望在其中添加代码
- 程序过于庞大或复杂,无法放在单个文件中
输入
| 输入 | 必需 | 描述 |
|---|---|---|
| C# 代码或意图 | 是 | 要运行的代码,或对脚本功能的描述 |
工作流
步骤 1:检查 .NET SDK 版本
运行 dotnet --version,确认已安装 SDK 并记下主版本号。基于文件的应用需要 .NET 10 或更高版本。如果版本低于 10,请改用旧版 SDK 的回退方案。
步骤 2:编写脚本文件
创建一个使用顶级语句的 .cs 文件。将它放在现有项目目录之外,以避免与 .csproj 文件冲突。
// hello.cs
Console.WriteLine("Hello from a C# script!");
var numbers = new[] { 1, 2, 3, 4, 5 };
Console.WriteLine($"Sum: {numbers.Sum()}");
指南:
- 使用顶级语句(不需要
Main方法、类或命名空间样板代码) - 将
using指令放在文件顶部 - 将类型声明(类、记录、枚举)放在所有顶级语句之后
步骤 3:运行脚本
dotnet hello.cs
该命令会自动生成并运行文件。构建结果会缓存,因此后续运行速度更快。使用 -- 传递参数:
dotnet hello.cs -- arg1 arg2 "multi word arg"
步骤 4:添加 NuGet 包(如有需要)
在文件顶部使用 #:package 指令引用 NuGet 包。务必指定版本:
#:package [email protected]
using Humanizer;
Console.WriteLine("hello world".Titleize());
步骤 5:清理
用户完成后,移除脚本文件。清除缓存的构建产物:
dotnet clean hello.cs
Unix shebang 支持
在 Unix 平台上,可以让 .cs 文件直接执行:
-
在文件第一行添加 shebang:
#!/usr/bin/env dotnet Console.WriteLine("I'm executable!"); -
设置执行权限:
chmod +x hello.cs -
直接运行:
./hello.cs
添加 shebang 时请使用 LF 换行符(而不是 CRLF)。此指令在 Windows 上会被忽略。
源生成 JSON
基于文件的应用默认启用原生 AOT。基于反射的 API(如 JsonSerializer.Serialize<T>(value))在 AOT 下会在运行时失败。请改用源生成序列化:
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;
转换为项目
当脚本不再适合放在单个文件中时,将其转换为完整项目:
dotnet project convert hello.cs
.NET 9 及更早版本的回退方案
如果 .NET SDK 版本低于 10,则无法使用基于文件的应用。请改用临时控制台项目:
mkdir -p /tmp/csharp-script && cd /tmp/csharp-script
dotnet new console -o . --force
将生成的 Program.cs 替换为脚本内容,然后使用 dotnet run 运行。使用 dotnet add package <name> 添加 NuGet 包。完成后移除该目录。
验证
-
dotnet --version显示 10.0 或更高版本(或已使用回退方案) - 脚本编译无错误(可使用
dotnet build <file>.cs显式检查) -
dotnet <file>.cs生成预期输出 - 会话结束后已清理脚本文件和缓存产物
常见问题
| 问题 | 解决方案 |
|---|---|
.cs 文件位于包含 .csproj 的目录中 | 将脚本移到项目目录之外,或使用 dotnet run --file file.cs |
#:package 未指定版本 | 指定版本:#:package [email protected],或使用 @* 指定最新版本 |
| 基于反射的 JSON 序列化失败 | 使用 JsonSerializerContext 进行源生成 JSON 序列化(参见源生成 JSON) |
| 构建行为异常或出现版本错误 | 基于文件的应用会从父目录继承 global.json、Directory.Build.props、Directory.Build.targets 和 nuget.config。如果继承的设置造成冲突,请将脚本移到独立目录 |
更多信息
完整的基于文件的应用参考文档,请参阅 https://learn.microsoft.com/en-us/dotnet/core/sdk/file-based-apps。