How I debug and run single cs files in vscode (WIP)
CSharp VSCode
With Java extension, we can easily run and debug a single .java file in vscode.
However, we can't do this with C#. We need to create a project, and set up debug for the project.
However, again, this doesn’t mean we can set up a workflow for C# single files for things like leetcode, testing laguage features, algorithms, other small or scripts.
We can use refelction. (Yes, refelction, again.)
Create a normal .net project and setup debug for vscode, and edit Program.cs:
using System.Reflection;
try {
string className = args[0];
var asm = Assembly.GetExecutingAssembly();
var entryClass = asm.GetType(className) ?? throw new EntryNotFound();
var entryMethod = entryClass.GetMethod("Main") ?? throw new EntryNotFound();
var returnVal = entryMethod.Invoke(null, null);
if (returnVal is Task task) {
await task;
}
}
catch (EntryNotFound) {
Console.WriteLine("Entry Not Found!");
}
class EntryNotFound : Exception { }
What this code is read a class name from the command line arguments, and find that class with the name using reflection, and invoke “Main” static method in the class. Check if the Main returns a Task ensure we can also write an async Main method.
So, we have our refelection set, how can we pass the file name into our program? After run “.NET: Generate Assets for Build and Debug” task in vscode, the C# extension will generate tasks.json and launch.json in .vscode folder for us. We can edit launch.json file to pass in command line arguments:
{
"version": "0.2.0",
"configurations": [
{
// Use IntelliSense to find out which attributes exist for C# debugging
// Use hover for the description of the existing attributes
// For further information visit https://github.com/dotnet/vscode-csharp/blob/main/debugger-launchjson.md
"name": ".NET Core Launch (console)",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build",
// If you have changed target frameworks, make sure to update the program path.
"program": "${workspaceFolder}/bin/Debug/net9.0/cs_dbg.dll",
"args": ["${fileBasenameNoExtension}"],
"cwd": "${workspaceFolder}",
// For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console
"console": "internalConsole",
"stopAtEntry": false
}
// other stuff...
]
}
In launch settings, we set args to ${fileBasenameNoExtension}, which means currently opened file’s basename with no file extension; we can find other variables we can use here: variables reference. Now we can easily run any class has a Main static method with the file name the same as class name.
Let’s creat a Hello.cs
// Hello.cs
public class Hello {
public static void Main() {
Console.WriteLine("Hello World");
}
}
When the file is open, hit debug button (F5). We can see the our hello program run succefully, and breakpoints also works.