When I began last year’s .NETpad modernization project, I intended to wrap-up the work with the help of GitHub Copilot or a similar AI. But because I took on too much work, I ended up splitting this modernization effort in two, and I’m now continuing with the second phase, in which I’ll add support for multiple tabs and documents, plus other new features. That said, I’ve never stopped thinking about how I might use AI to improve .NETpad. Indeed, I’ve been using AI in small ways for months.
The first big push was obvious enough: In December, Microsoft created a free tier of GitHub Copilot that gives everyone 2,000 code completions and 50 chat messages per month. I was already signing in to Visual Studio with my GitHub account, so all I had to do was enable GitHub Copilot in that app, and now I get inline code corrections and help using this incredible service.
Since then, I’ve also experimented with Google Gemini, OpenAI ChatGPT, and Anthropic Claude by asking each, in turn, to solve some specific issue I’ve run into with the app, or to confirm a solution I came up with independently. I haven’t really done much by way of head-to-head comparisons. Instead, I’ve just used one or the other to see whether AI could get me over some hump.
Much more recently, I used the Cursor AI code editor that Brad mentioned on First Ring Daily this past week to open the GitHub repository for the public version of .NETpad, which is the version I published at the end of last year. (The non-tabs-based version.) There, my intention was to start small, select a single method, and ask it whether it could be written more efficiently. But Cursor instead examined the entire project and issued a sweeping set of recommendations across the full source code of the app.
Each of these has been incredibly helpful. And it’s quite clear that AI can and will play a critical role in improving the quality of the code I write. This is especially important because, again, I’m not a professional developer and the code for this new tabs-based version of .NETpad is quite complex. I’m hitting the limits of my capabilities here (though I’m proud to say I did figure out the basics of managing multiple tabs and documents on my own, albeit in my own unsophisticated or non-professional way).
I now wish I hadn’t waited so long. Here are a few quick examples of why AI is such a game-changer for developers.
This feels a bit weird to write, but the code completion capabilities that GitHub Copilot delivers in Visual Studio are so good it can feel like magic. Indeed, this has caused me to laugh out loud multiple times. It’s like the AI is reading my mind. In some cases, I will write a comment and then start to write the code to implement that thing, and it just fills it all in, sometimes over multiple lines of code in a lengthy code block. That bit is somewhat understandable, given that my comment might be seen as a prompt of sorts.
There are also instances in which you can see how the AI might “guess ahead” by examining the “if” part of an if-else clause and then anticipating what you might want in the else part. This is a made-up example in which I don’t need an else part, but the initial code looks like so.

And if I start to type the “else” part, it offers up some possible code. Simple, but interesting.

But in other cases, there’s no comment or obvious trigger for a suggestion. I write a line of code, hit Enter, and it just suggests the next line of code. Every single time–and to date, I literally mean, every single time–the code it suggested is exactly what I was going to do next. This is not an example of that, sorry, I keep forgetting to capture it. But in this example, which won’t be in the app, I provided a comment, started a foreach block, and it provided code similar to that elsewhere in the app.

I have never seen anything exactly like this, but it’s like IntelliSense on steroids. Having AI guess, predict, or–God help us–know what I am going to do next is the parlor trick to end all parlor tricks. And that’s just AI inferring what I want. When I explicitly ask AI for help, as I’ve started doing across the standalone AI chatbots and now in Cursor (which uses Claude by default, though you can substitute ChatGPT), the results are arguably even more impressive.
As noted above, I’ve used the Anthropic Clause, Google Gemini, and OpenAI ChatGPT chat interfaces independently of Visual Studio or my code base to ask them specific questions that I might have otherwise Googled and then navigating through various StackOverflow results. This has always been impressive, regardless of the service. In addition to providing the answer with working code, each also explains how they arrived at that answer and provides a walkthrough of the produced code.
As an example, I’ve been working on a convoluted and self-inflicted issue related to the text insertion cursor in my app’s TextBox control, one of many document states that I need to track between open tabs. And so I asked ChatGPT (in this case) to, “Help me write a C# function for use with Windows Presentation Foundation (WPF) that will store the location of the text insertion cursor in a TextBox control with separate Line and Column values.”)
Here’s the code it produced.

And then the explanation.

This is a brief example, some of the responses are quite a bit more detailed. But it’s nicely done, and for something this explicit, a precise answer like this is appreciated.
I keep mentioning how concerned I am about code quality, this is a more nuanced topic than may be immediately obvious. At a high level, I did some code quality work last year on the 2024 version of the app (.NETpad 3.0 for Windows 11), and some of that involved not just rewriting blocks of code but organizing the code to be more modular. This work has continued with the new, tabs-based version of the app, and if anything, it’s even more important because of the added complexity. For example, I’ve put all the tabs-specific code in a separate Tabs.cs source file.
Since I started thinking about and then using AI in stilted ways in this project, I imagined getting an AI-powered code review, and I assumed that would happen inside Visual Studio. I also imagined that I could perform smaller code reviews on a per-method basis; in an episode of Scott & Mark Learn To…, Mark Russinovich discussed how he often prompts AI multiple times to just keep improving whatever code, and that apparently works well. I’ve been eager to try this. But much like one might clean the house before a house cleaner shows us, I sort of wanted to get the code in some presumably decent condition before AI judged it.
Anyway, Brad mentioned the Visual Studio Code-based Cursor AI editor the other day, so I installed it and took a look. Among many other things, this app lets you open a GitHub repository, so I opened my .NETpad 3.0 for Windows 11 repository, placing a copy of its full source code in the app (and locally on disk). I figured I could just select some code–like a method, or the code inside a method–and then prompt whatever AI it’s using–Claude by default, but ChatGPT optionally, as it turns out–to review that code. So I selected the code in some method and then typed “Is there a way to write this code more efficiently?” in the Chat box.
It then began examining the entire codebase, which was not my intention. But this, too, was something I wanted to see. And the results were fascinating to me.

It broke down its recommendations by topic.
Under “Document State Management,” it noted that I had made a list of DocumentTab objects called dts but never created a “proper document management class.” This is correct: I’ve made (really, updated) that class in the newer version of this app, the one I’m working on now (with tabs). In that version of the app, dts is just a placeholder the changes to come.
Under “Settings Management,” it noted that my LoadSettings() and SaveSettings() methods are both “quite long,” which is absolutely correct, and “could be split into smaller, focused methods.” And … Yeah. They could be. But there’s no reason for that level of modularity. Perhaps creating a Settings.cs file and just putting them there would be vaguely “better” (right now, both are in Backend.cs with many other helper methods). But this is one of a few recommendations tied to modularity, which I’ve been working on independently in the new version of the app, and that was interesting to me.
Under “UI State Management,” it told me there is “a lot of UI state management scattered throughout the code” and that I should “consider implementing a proper MVVM pattern to separate UI logic from business logic.” Doing so “would make the code more maintainable and testable.” And … sure. But that assumes I know MVVM, which I don’t. And as I think I’ve discussed elsewhere, in modularizing the app’s code, I’ve been sort of walking backward into an MVVM-like separation of UI and business logic in my own simplistic way. For example, I use MainWindow.xaml.cs (and other similar files) only for event handler methods. I created a Backend.cs file for “helper” methods. And in the more recent version of the app, there is a Tabs.cs for tabs-related methods. This isn’t MVVM. But it’s a step towards that kind of modularity and separation.
There were other notes related to error handling, which is indeed sporadic. Code duplication, which is interesting for the reason noted above: I’ve worked on reducing that in the more recent version of the app, and this is a key area for code improvement generally. It specifically told me I might combine AutoSaveEnable() and AutoSaveDisable() into a single method, which is interesting. (Like a ToggleAutoSave(), I guess.) And it told me there are “several magic numbers” in the code that should be defined as constants. Like my timer interval of 30,000 ms, which I always intended to make a user-configurable option anyway. But fair enough.
There were two more notes about modularity, both of interest.
The first concerned event handling, noting that “some event handlers are quite long and could be split into smaller methods.” This was amazing to me, almost, because that is a specific goal of mine for the new version of the app: Minimize the code in all event handlers, modularizing where possible into one or more (of what I think of as) helper methods. This is especially true in instances where I was previously reusing/repeating code.
The second was unexpected: It recommended moving code related to file operations into a “separate service class,” so something like FileOps.cs or whatever. The code for file operations is currently modular, with an event handler like OpenCommand_Executed() calling a helper method like OpenDocument(), where the latter method is currently in Backend.cs. But this and one or two other suggestions seem to indicate that further modularization might be better. Instead of a single Backend.cs, have several “modules” (files/classes) with a more logical separation.
So … Yeah. Maybe.
The problem with modularization is that I end up forgetting where things are. Using the above example, OpenCommand_Executed() is in MainWindow.xaml.cs because it’s an event handler tied to the main app window. And it calls OpenDocument(), which I wrote and placed in Backend.cs as noted. But it also calls DisplayConfirmationDialog() which is … where? Looking, I find that it’s in Backend.cs too, but I didn’t know that off the top of my head. And some other methods are even less obvious.
Granted, you can Ctrl + click on any of these method names in Visual Studio to go to the method, and that shows you where it’s located. But I feel like modularization is good until it isn’t. You can have too little (or no) modularization. But you can also have too much modularization. That makes debugging difficult because it’s sometime unclear where code is and which code is causing a problem.
But whatever. This is part of the fun and responsibility of maintaining any code base. There are lots of decisions to be made. And as noted up top, AI can help. A lot.
And I will keep using it to improve .NETpad. So there will be more soon.
With technology shaping our everyday lives, how could we not dig deeper?
Thurrott Premium delivers an honest and thorough perspective about the technologies we use and rely on everyday. Discover deeper content as a Premium member.