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.

Example for .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.

Debug the cs file in vscode