csharp-scripts

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

C# Scripts

C# 脚本

When to Use

使用场景

  • Testing a C# concept, API, or language feature with a quick one-file program
  • Prototyping logic before integrating it into a larger project
  • 使用单文件程序快速测试C#概念、API或语言特性
  • 在将逻辑集成到大型项目之前进行原型开发

When Not to Use

不适用场景

  • The user needs a full project with multiple files or project references
  • The user is working inside an existing .NET solution and wants to add code there
  • The program is too large or complex for a single file
  • 用户需要包含多个文件或项目引用的完整项目
  • 用户正在现有.NET解决方案中工作并希望在其中添加代码
  • 程序过于庞大或复杂,不适合单文件形式

Inputs

输入项

InputRequiredDescription
C# code or intentYesThe code to run, or a description of what the script should do
输入项是否必填描述
C#代码或需求描述要运行的代码,或脚本应实现功能的描述

Workflow

工作流程

Step 1: Check the .NET SDK version

步骤1:检查.NET SDK版本

Run
dotnet --version
to verify the SDK is installed and note the major version number. File-based apps require .NET 10 or later. If the version is below 10, follow the fallback for older SDKs instead.
运行
dotnet --version
验证SDK已安装并记录主版本号。基于文件的应用需要.NET 10或更高版本。如果版本低于10,请改用.NET 9及更早版本的兼容方案

Step 2: Write the script file

步骤2:编写脚本文件

Create a single
.cs
file using top-level statements. Place it outside any existing project directory to avoid conflicts with
.csproj
files.
csharp
// hello.cs
Console.WriteLine("Hello from a C# script!");

var numbers = new[] { 1, 2, 3, 4, 5 };
Console.WriteLine($"Sum: {numbers.Sum()}");
Guidelines:
  • Use top-level statements (no
    Main
    method, class, or namespace boilerplate)
  • Place
    using
    directives at the top of the file
  • Place type declarations (classes, records, enums) after all top-level statements
创建一个使用顶级语句的单个
.cs
文件。将其放在现有项目目录之外,避免与
.csproj
文件冲突。
csharp
// hello.cs
Console.WriteLine("Hello from a C# script!");

var numbers = new[] { 1, 2, 3, 4, 5 };
Console.WriteLine($"Sum: {numbers.Sum()}");
编写准则:
  • 使用顶级语句(无需
    Main
    方法、类或命名空间模板代码)
  • using
    指令放在文件顶部
  • 将类型声明(类、记录、枚举)放在所有顶级语句之后

Step 3: Run the script

步骤3:运行脚本

bash
dotnet hello.cs
Builds and runs the file automatically. Cached so subsequent runs are fast. Pass arguments after
--
:
bash
dotnet hello.cs -- arg1 arg2 "multi word arg"
bash
dotnet hello.cs
自动构建并运行文件。构建结果会被缓存,后续运行速度更快。可在
--
后传递参数:
bash
dotnet hello.cs -- arg1 arg2 "multi word arg"

Step 4: Add NuGet packages (if needed)

步骤4:添加NuGet包(如有需要)

Use the
#:package
directive at the top of the file to reference NuGet packages. Always specify a version:
csharp
#:package Humanizer@2.14.1

using Humanizer;

Console.WriteLine("hello world".Titleize());
在文件顶部使用
#:package
指令引用NuGet包,必须指定版本:
csharp
#:package Humanizer@2.14.1

using Humanizer;

Console.WriteLine("hello world".Titleize());

Step 5: Clean up

步骤5:清理

Remove the script file when the user is done. To clear cached build artifacts:
bash
dotnet clean hello.cs
使用完毕后删除脚本文件。如需清理缓存的构建产物:
bash
dotnet clean hello.cs

Unix shebang support

Unix shebang支持

On Unix platforms, make a
.cs
file directly executable:
  1. Add a shebang as the first line of the file:
    csharp
    #!/usr/bin/env dotnet
    Console.WriteLine("I'm executable!");
  2. Set execute permissions:
    bash
    chmod +x hello.cs
  3. Run directly:
    bash
    ./hello.cs
Use
LF
line endings (not
CRLF
) when adding a shebang. This directive is ignored on Windows.
在Unix平台上,可使
.cs
文件直接可执行:
  1. 在文件首行添加shebang:
    csharp
    #!/usr/bin/env dotnet
    Console.WriteLine("I'm executable!");
  2. 设置执行权限:
    bash
    chmod +x hello.cs
  3. 直接运行:
    bash
    ./hello.cs
添加shebang时请使用LF换行符(而非CRLF)。该指令在Windows上会被忽略。

Source-generated JSON

源代码生成式JSON

File-based apps enable native AOT by default. Reflection-based APIs like
JsonSerializer.Serialize<T>(value)
fail at runtime under AOT. Use source-generated serialization instead:
csharp
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;
基于文件的应用默认启用原生AOT。像
JsonSerializer.Serialize<T>(value)
这类基于反射的API在AOT环境下运行时会失败,请改用源代码生成式序列化:
csharp
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;

Converting to a project

转换为完整项目

When a script outgrows a single file, convert it to a full project:
bash
dotnet project convert hello.cs
当脚本不再适合单文件形式时,将其转换为完整项目:
bash
dotnet project convert hello.cs

Fallback for .NET 9 and earlier

.NET 9及更早版本的兼容方案

If the .NET SDK version is below 10, file-based apps are not available. Use a temporary console project instead:
bash
mkdir -p /tmp/csharp-script && cd /tmp/csharp-script
dotnet new console -o . --force
Replace the generated
Program.cs
with the script content and run with
dotnet run
. Add NuGet packages with
dotnet add package <name>
. Remove the directory when done.
如果.NET SDK版本低于10,则无法使用基于文件的应用,请改用临时控制台项目:
bash
mkdir -p /tmp/csharp-script && cd /tmp/csharp-script
dotnet new console -o . --force
替换生成的
Program.cs
为脚本内容,然后使用
dotnet run
运行。使用
dotnet add package <name>
添加NuGet包。使用完毕后删除该目录。

Validation

验证项

  • dotnet --version
    reports 10.0 or later (or fallback path is used)
  • The script compiles without errors (can be checked explicitly with
    dotnet build <file>.cs
    )
  • dotnet <file>.cs
    produces the expected output
  • Script file and cached artifacts are cleaned up after the session
  • dotnet --version
    显示10.0或更高版本(或已使用兼容方案)
  • 脚本编译无错误(可通过
    dotnet build <file>.cs
    显式检查)
  • dotnet <file>.cs
    产生预期输出
  • 会话结束后已清理脚本文件和缓存的构建产物

Common Pitfalls

常见陷阱

PitfallSolution
.cs
file is inside a directory with a
.csproj
Move the script outside the project directory, or use
dotnet run --file file.cs
#:package
without a version
Specify a version:
#:package PackageName@1.2.3
or
@*
for latest
Reflection-based JSON serialization failsUse source-generated JSON with
JsonSerializerContext
(see Source-generated JSON)
Unexpected build behavior or version errorsFile-based apps inherit
global.json
,
Directory.Build.props
,
Directory.Build.targets
, and
nuget.config
from parent directories. Move the script to an isolated directory if the inherited settings conflict
陷阱解决方案
.cs
文件位于包含
.csproj
的目录中
将脚本移至项目目录之外,或使用
dotnet run --file file.cs
#:package
未指定版本
指定版本:
#:package PackageName@1.2.3
或使用
@*
获取最新版本
基于反射的JSON序列化失败使用
JsonSerializerContext
进行源代码生成式JSON序列化(参见源代码生成式JSON
意外的构建行为或版本错误基于文件的应用会从父目录继承
global.json
Directory.Build.props
Directory.Build.targets
nuget.config
。如果继承的设置存在冲突,请将脚本移至独立目录

More info

更多信息