GitHub - waf/CSharpRepl: 一个具有语法高亮的命令行 CREPL – 交互式探索语言、库和 NuGet 包
GitHub - waf/CSharpRepl: 一个具有语法高亮的命令行 C# REPL – 交互式探索语言、库和 NuGet 包
一个跨平台的命令行 REPL(读取-求值-输出循环),用于快速实验和探索 C#。它支持智能提示、安装 NuGet 包,以及引用本地 .NET 项目和程序集。
C# REPL 提供以下功能:
- 通过 ANSI 转义序列实现语法高亮
- 带文档和重载导航的智能提示(Intellisense)
- 自动格式化输入的代码
- NuGet 包安装
- 引用本地程序集、解决方案和项目
- 使用语法高亮和丰富的 Spectre.Console 格式转储并探索对象
- 检查正在运行的 .NET 应用程序,并在该应用程序内部运行 REPL,能够访问应用状态并替换实时方法
- 通过 Source Link 导航到源代码
- IL 反汇编和“降级”C# 反编译(支持 Debug 和 Release 模式,使用 ILSpy)
- 通过 OpenAI、Anthropic、Gemini、Grok、DeepSeek、Mistral/Codestral 或任何兼容 OpenAI 的提供商进行 AI 代码补全(自带 API 密钥)
- 快速且无闪烁的渲染。使用“diff”算法仅渲染变化的部分。
C# REPL 是一个 .NET 10 全局工具,可在 Windows、Mac OS 和 Linux 上运行。可以通过以下方式从 NuGet 安装:
dotnet tool install -g csharprepl
如果您运行的是 Mac OS Catalina(10.15)或更高版本,请确保遵循屏幕上打印的任何附加说明。您可能需要更新 PATH 变量才能使用 .NET 全局工具。
安装完成后,运行 csharprepl 即可开始。您可以通过运行 dotnet tool update -g csharprepl 来更新 C# REPL。
默认主题使用与 Visual Studio 深色模式相同的颜色,并且可以使用 theme.json 文件创建自定义主题。此外,可以通过提供 --useTerminalPaletteTheme 命令行选项来使用终端的颜色。要完全禁用颜色,请设置 NO_COLOR 环境变量。
在提示符下输入一些 C# 代码,然后按 Enter 键运行。如果有结果,将会打印出来:
> Console.WriteLine("Hello World")
Hello World
> DateTime.Now.AddDays(8)
[6/7/2021 5:13:00 PM]
要计算多行代码,请使用 Shift+Enter 插入换行:
> var x = 5;
var y = 8;
x * y
40
此外,如果语句不是“完整语句”,按 Enter 时会自动插入换行。例如,在下面的代码中,第一行不是一个语法完整的语句,所以当我们按 Enter 时会转到新的一行:
> if (x == 5)
| // 光标位置,在按 Enter 之后
最后,按 Ctrl+Enter 将显示结果的“详细视图”。例如,对于下面的 DateTime.Now 表达式,第一行我们按了 Enter,第二行我们按了 Ctrl+Enter 来查看更详细的输出:
> DateTime.Now // 按 Enter 显示合理的表示
[5/30/2021 5:13:00 PM]
> DateTime.Now // 按 Ctrl+Enter 显示详细的表示
[5/30/2021 5:13:00 PM] {
Date: [5/30/2021 12:00:00 AM],
Day: 30,
DayOfWeek: Sunday,
DayOfYear: 150,
Hour: 17,
InternalKind: 9223372036854775808,
InternalTicks: 637579915804530992,
Kind: Local,
Millisecond: 453,
Minute: 13,
Month: 5,
Second: 0,
Ticks: 637579915804530992,
TimeOfDay: [17:13:00.4530992],
Year: 2021,
_dateData: 9860951952659306800
}
关于分号的说明:C# 表达式不需要分号,但语句需要。如果语句缺少必需的分号,将添加换行而不是尝试运行语法不完整的语句;只需输入分号即可完成语句。
> var now = DateTime.Now; // 赋值语句,需要分号
> DateTime.Now.AddDays(8) // 表达式,不需要分号
[6/7/2021 5:03:05 PM]
当您完成会话后,可以输入 exit 或按 Ctrl+D 退出。
使用 #r 命令添加程序集或 NuGet 引用。
- 对于程序集引用,运行
#r "AssemblyName"或#r "path/to/assembly.dll" - 对于项目引用,运行
#r "path/to/project.csproj"。解决方案文件(.sln和.slnx)也可以被引用。 - 对于 NuGet 引用,运行
#r "nuget: PackageName"安装包的最新版本,或#r "nuget: PackageName, 13.0.5"安装特定版本(此处为 13.0.5)。
要在 REPL 中运行 ASP.NET 应用程序,请使用 --framework 参数启动 csharprepl 应用程序,指定 Microsoft.AspNetCore.App 共享框架。然后,使用上面的 #r 命令引用应用程序 DLL。更多详情请参见 Configuring CSharpRepl。
csharprepl --framework Microsoft.AspNetCore.App
使用 #load 指令运行 C# 脚本文件(.csx),例如 #load "path/to/script.csx"。这对于初始化会话很方便,因为脚本定义的任何引用、命名空间和变量在之后仍然可用。
除了在 csharprepl 自己的进程中评估代码的标准 REPL 之外,csharprepl 还可以附加到其他 .NET 应用程序并在其中评估表达式,读取和写入实时应用程序状态(例如静态变量和从 DI 解析的服务)。
警告
连接到启用了检查器的进程相当于在该进程内以其权限运行任意代码。这是一个开发和诊断工具;切勿在生产进程上启用检查器。
CSharpRepl 将真正的 Roslyn 脚本引擎注入目标应用程序,因此您可以在该应用程序中运行不受限制的 C#。这不是调试器;不支持断点、单步执行和非协作附加。
目标源代码不需要修改,但应用程序必须通过从设置了两个特殊环境变量的 shell 中运行来“选择加入”,这两个变量允许 CSharpRepl 注入 REPL:
- 打印用于启动应用程序的环境变量:
csharprepl inspect init # 自动检测您的 shell,或传递例如 --shell pwsh - 设置上一步中的环境变量,并在该 shell 中启动您的应用程序。您不应将这些设置为机器的永久环境变量。仅在计划启动目标应用程序的 shell 中设置它们。
- 通过进程 ID 附加到应用程序:
csharprepl inspect list # 列出可附加的进程及其进程 ID。 csharprepl inspect 1234 # 附加到进程 ID 例如 1234 的进程
这将在目标应用程序中启动 REPL。您可以尝试的一些操作:
- 静态变量:通过完全限定名称引用它们,例如
MyApp.Program.SomeStatic(可读写)。 - DI 服务(ASP.NET Core 或通用主机应用程序):
services.GetRequiredService<T>()或简写Get<T>()。检查器通过 .NET 的主机挂钩捕获应用程序的根服务提供程序。
您还可以替换目标中的实时方法。定义一个委托,然后用它修补方法:
- 定义一个与目标匹配的委托。实例方法将实例作为第一个参数:
Func<MyApp.OrderService, decimal, string, decimal> half = (svc, qty, unit) => qty * unit * 0.5m; #replace MyApp.OrderService.CalculatePrice with half:替换原始方法。#wrap MyApp.OrderService.CalculatePrice with logged:包装它。替换的第一个参数是一个orig委托,它调用原始方法。#patches:列出活动补丁。#revert或#revert all:撤销它们。
补丁立即生效,并在目标中持续存在,直到被撤销或进程退出。