不夸张地说NetPad算是我最近半年在C#开发环境里用得最值回票价的一个工具。如果你平时写C#常需要快速验证一段代码逻辑、跑一个临时数据处理脚本、或者查一下数据库里的数据但又不愿意每次都为了这几行代码去创建一个完整项目那这个开源的、跨平台的C#编辑器就非常适合你。它本质上是一个基于.NET生态的“即写即运行”脚本环境类似LINQPad的开源替代品但做到了Windows、macOS、Linux三端通吃而且完全免费、代码开源。我最早知道NetPad是因为关注了GitHub上的.NET开源项目榜单。当时正好在折腾一个数据清洗的活儿每次都要开VS建项目、等编译、跑完再清理来回折腾得心累于是就开始研究有没有更轻量的方案。试过dotnet-script也试过直接裸敲dotnet run都不够顺手直到把NetPad装起来第一感觉是这不就是我一直在找的东西吗。这篇就从一个实际使用者的角度把这个工具拆开聊一聊——它到底能做什么、怎么用、有哪些优势又有哪些坑需要注意。1. NetPad到底是什么为什么要用它1.1 它的定位与技术底座NetPad是一个面向C#开发者的轻量级编辑器核心定位是“C#脚本即时执行环境”。你用它在空白页面里写几行C#按一下运行右侧输出面板直接展示结果不需要创建工程文件、不需要配置启动项、不需要嗑Main函数连保存逻辑都比传统IDE省心太多。从技术层面说NetPad是构建在.NET最新的技术栈之上的界面层用了Avalonia这个开源的跨平台UI框架所以它才能以较低成本实现Windows、Linux、macOS三端一致体验。执行引擎方面NetPad底层和Roslyn编译服务深度绑定脚本会经过动态编译后加载执行——这一点和很多“简单包装一下的编辑器”完全不同它是真正实现了“编译-运行”闭环的。1.2 它解决了什么实际问题不爱用传统项目结构来跑临时代码的人基本都能GET到NetPad的价值。拿我自己常见的几个场景来说验证一个正则表达式是否匹配预期文本快速测试某个NuGet包的API调用方式从Excel读取数据做分组统计再导出结果连接开发库执行查询对返回结果做二次加工临时算一组算法结果比如排序、去重、模拟数据这些场景如果用传统方式做要么得新建控制台项目并在临时文件里堆代码要么得打开单元测试项目写测试方法要么就得切到命令行去执行SQL。NetPad把这些全部装进一个窗口文件打开就能写写完就运行还能保存成脚本反复使用。对我这种经常做数据核对和接口联调的人来说效率提升不是一点半点。1.3 和主流竞品的横向对比说到C#脚本工具很多人第一个想到的是LINQPad。LINQPad确实非常强大尤其它的Dump功能堪称神器但问题是它高级功能都要靠收费授权解锁并且跨平台体验一直不太顺畅。NetPad作为开源方案最大的优势是免费、跨平台、代码透明你甚至可以直接去GitHub上看它的源码实现。如果和dotnet-script这种命令行工具比NetPad的图形界面、表格化输出、数据库连接管理又是压倒性的优势。dotnet-script适合极客式的CLI流但要在上手成本、可视化反馈、工程化管理几个维度综合打分NetPad绝对更贴近普通开发者的使用习惯。2. 安装和跨平台环境准备2.1 Windows、macOS、Linux三平台安装差异NetPad的安装分发方式比较常规Windows平台的exe安装包、macOS的dmg镜像、Linux的AppImage包在GitHub的Releases页面都能找到。根据自己系统下载对应版本就行这一步基本没难度。macOS有一点要注意因为NetPad不是从App Store分发也没有做Apple官方公证所以首次打开时会被Gatekeeper拦截。初次使用你需要在“系统设置 - 隐私与安全性”里手动允许如果终端打开直接提示“应用已损坏”多半是隔离属性没删掉sudo xattr -dr com.apple.quarantine /Applications/NetPad.appLinux下命令行运行会更直接chmod x NetPad-*.AppImage ./NetPad-*.AppImage如果Linux桌面环境缺依赖导致无法启动可以先安装libx11相关的运行库或者用官方提供的命令行安装脚本走一遍实测Ubuntu和Debian系系统都没问题。2.2 .NET运行时版本与兼容性细节NetPad发布时通常会带上自包含的运行时所以大多数用户不用额外安装.NET SDK也能跑起来。但如果你机器上已经有多版本的.NET环境建议还是理顺一下版本关系尤其是NetPad版本升级后可能要求特定版本的.NET运行时这时你本地的dotnet环境若低于要求就很容易出现启动闪退。我自己遇到过一种情况机器上装了.NET 6和.NET 8两套SDKNetPad默认使用环境变量里的dotnet版本加载运行时结果脚本里引用的NuGet包依赖.NET 8的APINetPad却一直在旧版本的运行时里执行导致程序集加载异常。解决办法很简单检查系统PATH里dotnet的指向确保NetPad能加载到正确的运行时版本。2.3 工作区和项目文件组织NetPad和VS Code类似也有“工作区”的概念。你可以把脚本按项目或按用途分门别类放进不同的工作区比如“数据分析”、“接口测试”、“LeetCode刷题”切换工作区就是切换一套上下文环境。我的习惯是在本地创建一个专门存放NetPad脚本的目录用Git做版本管理。这样写过的一些比较通用的脚本片段能留存下来下次用的时候直接复制或加载避免重复劳动。NetPad脚本默认以.csx为后缀本质上是纯文本文件用任何编辑器都能打开所以版本控制非常友好。3. 核心功能拆解与实用场景3.1 C#脚本如何做到即时执行NetPad的交互方式很直接打开脚本写代码点运行。它内部处理逻辑大致是把你写的代码片段包装成一个临时类动态编译成程序集再在独立进程里加载运行。你可以在脚本里写表达式运行结果直接显示也可以写完整的类、方法、async任务甚至引用外部包。一个最简单的表达式脚本Enumerable.Range(1, 100).Where(x x % 3 0).Sum()运行后输出面板会显示结果还可以看到执行用时和内存占用。如果你写的是一段包含输出语句的代码块比如用Console.WriteLine打印内容NetPad同样会把这些输出按顺序捕获下来。还有一个细节NetPad的脚本支持声明局部函数、定义类型、使用顶级语句和await。这意味着你可以写出类似下面这种比较复杂的逻辑而不用另外建类库项目async Taskstring CallApiAsync(string url) { using var http new HttpClient(); return await http.GetStringAsync(url); } var data await CallApiAsync(https://jsonplaceholder.typicode.com/todos/1); data最后一行data作为表达式结果输出NetPad会把它格式化成结构化的JSON视图便于阅读。这种“既能写过程代码又能看结构化结果”的交互方式比单纯用Console.WriteLine打日志舒服太多。3.2 数据库连接与查询比想象中顺手NetPad对数据库连接的支持是它的加分项之一。它内置了对SQL Server、PostgreSQL、MySQL、SQLite、Oracle等主流数据库的支持。你可以在界面里新建连接填写连接信息然后NetPad会把它保存到配置文件中后续脚本里直接通过某只“内置对象”访问数据库。以SQLite为例新建连接时选择“SQLite”指定数据库文件路径后脚本里可以直接执行SQL查询并把结果集以表格形式展示Db.Query(SELECT * FROM products WHERE price price, new { price 100 })注意这里的Db对象是NetPad注入的全局上下文无需手动打开连接或做太多管道工作。执行结果会直接在输出面板里渲染成表格还可以一键转成JSON格式查看。对经常做数据核对的开发者来说这意味着你可以用C#和SQL混合操作数据查询结果出来以后直接用LINQ做二次处理整个流程非常顺畅。不过有一点要提醒数据库连接虽然方便但NetPad本质是开发调试工具不是生产级数据库管理客户端。生产环境的连接串最好还是单独保护不要保存到公共工作区的配置文件里安全第一。3.3 NuGet包引用实现脚本级复用NetPad支持直接在脚本中引用NuGet包。有GUI操作方式在右侧“引用”面板搜索包并添加即可之后NetPad会自动添加对应的指令到脚本头部。如果你更喜欢直接编辑脚本可以手动写引用指令#r nuget: Newtonsoft.Json, 13.0.3添加后脚本里就能直接使用Newtonsoft.Json的API。这个能力极大扩展了脚本的功能边界需要解析Excel引入ExcelDataReader需要操作Word引入OpenXML需要做HTTP请求System.Net.Http已经内置直接using就能用。我自己有一个常用的“万能模板”脚本里面预置了我最常用的几个包引用和辅助函数比如ClosedXML处理Excel、Dapper操作数据库、NodaTime处理时间。每次新建脚本基于这个模板开始写绝大多数场景都能直接覆盖再也不用为了一个小功能去创建完整项目。3.4 多文件脚本加载复杂逻辑也能拆分早期NetPad只支持单文件脚本后面的版本已经加入了多文件加载机制。你可以把公共代码放到单独的.csx文件里再在主脚本中通过#load指令引入#load common/Extensions.csx #load common/Database.csx这种方式很适合组织稍微复杂一点的临时工具。比如我写过一个小系统从某个外部接口拉取数据做清洗转换再批量灌入数据库。整个逻辑拆成了三个文件接口请求封装、数据清洗扩展方法、主流程脚本。如果挤在一个文件里会超过五百行调试起来很费劲拆成模块后哪个环节出问题直接定位那个文件就行。要注意被#load进来的脚本里的using和#r指令在主脚本编译时是共享上下文的所以不同文件里不要重复定义同名的类和扩展方法否则会出现二义性错误。这个和C#编译项目的引用逻辑有些差异刚上手的人容易踩。4. 实操记录用NetPad完成一次真实的数据处理任务4.1 任务背景与方案拆解有一次运营部门丢给我一张Excel表里面是上万条用户注册明细要求按注册渠道和城市做交叉统计最后输出一份带排名的统计表。传统方案是用Excel透视表但数据量一上万Excel操作就开始卡而且这种统计每周都要做一次不能一直靠人工处理。我决定用NetPad来写一个可重复执行的脚本。方案拆解如下用ExcelDataReader读取.xlsx文件用LINQ做分组聚合用ClosedXML生成结果Excel统计数据输出到NetPad面板同时保存文件4.2 具体实现与运行过程首先在脚本顶部添加NuGet包引用#r nuget: ExcelDataReader #r nuget: ExcelDataReader.DataSet #r nuget: ClosedXML using System.Text; using System.Data; using ExcelDataReader; using ClosedXML.Excel;然后注册编码提供者这点非常关键。ExcelDataReader在读取中文字符时依赖正确的编码注册Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);接下来读取Excelusing var stream File.OpenRead(用户注册明细.xlsx); using var reader ExcelReaderFactory.CreateReader(stream); var ds reader.AsDataSet(); var dt ds.Tables[0];然后写分组统计逻辑var rows dt.Rows.CastDataRow(); var stats rows .GroupBy(r new { City r[城市]?.ToString(), Channel r[注册渠道]?.ToString() }) .Select(g new { g.Key.City, g.Key.Channel, Count g.Count() }) .OrderByDescending(x x.Count) .ToList();最后把结果输出到新Excelusing var wb new XLWorkbook(); var ws wb.Worksheets.Add(统计结果); ws.Cell(1, 1).Value 城市; ws.Cell(1, 2).Value 注册渠道; ws.Cell(1, 3).Value 数量; for (int i 0; i stats.Count; i) { ws.Cell(i 2, 1).Value stats[i].City; ws.Cell(i 2, 2).Value stats[i].Channel; ws.Cell(i 2, 3).Value stats[i].Count; } wb.SaveAs(统计结果.xlsx);脚本运行总共耗时不到三秒NetPad输出面板里还直接列出了统计结果的前几条记录预览。和以前在Excel里操作半个小时、结果还不一定正确相比这个效率可以说是碾压级的。之后的每周统计只需要把新表覆盖到同样路径运行一下脚本就能拿到结果连公式都不用重新设计。4.3 这个案例带来的体会做完这个任务我最大的感受是NetPad解决的关键问题不是“运行C#代码”这件事本身而是把“从想法到结果”的距离压缩到了最短。以前写工具会纠结要不要建项目、要不要考虑程序集结构现在完全不需要打开就是干。任务做完脚本文件留档下次复用或改造都极其方便。5. 常见问题排查与避坑记录5.1 高频问题速查表我在使用过程中积累了一些常见问题和解决方案整理成表方便大家直接参考现象可能原因解决方案启动时闪退无错误提示本地.NET运行时版本与NetPad要求不一致检查PATH变量中dotnet版本或安装NetPad要求的运行时版本脚本引用NuGet包后编译报错包版本冲突或目标框架不兼容在引用指令中明确指定包版本检查包是否支持当前.NET版本ExcelDataReader读取中文乱码未注册编码提供程序先执行Encoding.RegisterProvider(CodePagesEncodingProvider.Instance)数据库连接超时长时间未操作连接池断开在脚本中重新获取连接或检查数据库网络策略输出面板结果太长被截断默认输出长度限制在设置里调整输出限制或改用文件方式导出结果Linux下无法启动缺少系统依赖库安装libx11、libice等基础库尝试AppImage与命令行包两种方式5.2 避坑心得和调试技巧有几个经验是用了很久才慢慢体会到的这里专门分享出来。第一NetPad的脚本文件虽然叫.csx但它对顶层语句的处理方式和纯C#脚本工具不完全一样。如果你从别的地方复制一段带顶层using namespace的代码进来大概率会编译失败。NetPad更倾向于脚本头部用#r和#load做引用正文直接写代码不要把完整.Program结构搬进来。第二做数据库查询时Db.Query方法返回的结果集在输出面板里展示很友好但如果结果集特别大比如几万行面板渲染会卡顿。这种场景最好在脚本里主动Limit一下或者在SQL里用TOP/limit子句限制返回条数只把必要的数据拉到内存处理。第三如果你脚本里使用了HttpClient一定要记得用完释放掉。NetPad虽然运行在独立的进程环境里但如果脚本长期运行或者频繁执行不释放连接资源会占用大量socket端口最终影响本机网络连接。第四NetPad的NuGet缓存目录和Visual Studio的全局NuGet缓存是公用的。如果你在VS里清过缓存NetPad这边的引用也可能需要重新解析。此时可以到NetPad设置里清理一次本地NuGet缓存并重新加载。5.3 脚本运行效率的小优化NetPad脚本本质上是动态编译首次执行会比传统的预制项目慢一些因为它要经历编译和加载。如果你的脚本很复杂、引用了大量NuGet包首次运行的耗时可能在几秒到十几秒之间这属于正常现象。但如果你发现同一个脚本每次执行都非常慢可以检查是不是有数据库连接或文件I/O拖了后腿必要时在脚本里做结果缓存减少重复查询。6. 跨平台体验与实际应用场景再延伸6.1 在不同系统上的日常使用感受我在macOS和Windows上都用NetPad写过代码。macOS上的界面渲染流畅度不错中文输入法也兼容良好整体感觉和原生应用没太大差别。Windows上的体验则更“稳”毕竟.NET生态在Windows上是主场文件关联、右键菜单这类小功能都更加顺滑。Linux我没作为主力开发环境用过但在Ubuntu虚拟机里测试过能正常安装、运行和连接SQLite数据库对Linux党来说已经够用。要说有什么不足就是NetPad在UI美学上还是有点偏“工程师审美”不如一些商业化IDE精致。但对工具类应用来说效率和功能永远排在第一位界面简洁反而是加分项。6.2 可以配合使用的周边工具NetPad本身定位是轻量脚本环境如果你需要更完整的项目开发体验可以把它和VS Code、Rider或Visual Studio结合使用。我的工作流是项目开发用VS Code/Rider临时脚本和数据处理用NetPad两边通过Git仓库共享代码和脚本文件。这样既不影响正式项目的工程质量又不牺牲临时任务的灵活性。另外NetPad脚本可以当作一种“代码笔记”来用。我在学习一个新的NuGet库时会专门建一个脚本文件把手册里的示例代码跑一遍再改成自己需要的参数最后留下一份带注释的可用脚本。相当于给自己维护了一份可执行的API知识库比单纯收藏文档链接实用太多。7. 一些个人感想与后续玩法建议如果你也经常面对“为跑几行代码建一个工程”的尴尬NetPad大概率能帮你解脱出来。我在实际使用中最深的体会是一个顺手的工具本质上是在帮你降低“开始做事”的心理门槛。以前面对一个小需求光是创建项目、等编辑器加载、配置命名空间就要花掉不少耐心现在打开NetPad十秒内就能跑起来这种即时反馈的感觉非常舒服。最后想分享一个扩展玩法把NetPad脚本作为自动化小工具的一部分。比如配合系统定时任务定期执行一个数据汇总脚本把结果输出到固定路径再由其他流程去消费。当然NetPad本身不是为无人值守服务设计的这里只是提供一个思路——它的脚本能力足够灵活能干很多超出“编辑器”三个字预期的事情。工具毕竟是工具重要的是怎么利用它解决自己手头的问题。NetPad在过去一年多里帮我省下了大量搭建临时项目的时间也希望这篇文章能帮你省下一些摸索的成本。如果你也有关于NetPad的神仙用法或者踩坑经历欢迎在评论区一起交流。
