Skip to Content
Course content

4: Compiling and Running C# Applications

Click on the "Edit" button in the top corner of the screen to edit your slide content.

By now, you've probably spent some time writing code in an editor and hitting a "Run" button. It feels like magic—you click a green arrow, and your code executes. But as a professional, relying on that button is a dangerous habit. It abstracts away the actual process of how C# transforms from a text file into something a computer can execute. If you don't understand the compilation pipeline, you're going to be completely lost the first time a build fails on a CI/CD server or when you need to deploy an app to a machine that doesn't have Visual Studio installed.

The manual struggle of csc

In the early days, or if you're following a very outdated tutorial, you might see people talking about the C# Compiler (csc.exe) directly. Imagine we're building a simple DeadlineTracker—a tool that calculates how many days are left until a project is due. In the naive approach, you'd open a terminal and call the compiler manually:

csc DeadlineTracker.cs

At first, this seems fine. You get a .exe file, and you run it. But the moment you add a second file for your logic or try to use a third-party library for date formatting, this approach falls apart. You end up with a monstrous command string, manually listing every single source file and every single reference path. It's brittle, it's tedious, and it's nearly impossible to share with a teammate because your file paths are different from theirs. I've seen juniors waste hours trying to "fix" their code when the actual problem was just a missing filename in a manual compile command.

Letting the .NET CLI handle the heavy lifting

The modern, professional way to handle this is through the .NET CLI. Instead of thinking about individual files, we think about projects. When you use dotnet new console, you aren't just getting a template; you're getting a .csproj file. This is the blueprint for your application. It tells the compiler exactly which version of .NET to use and which dependencies are required.

Instead of calling csc, you use dotnet build. This command looks at that project file and orchestrates everything. It handles the dependency graph and compiles your code into an Intermediate Language (IL) assembly. When you run dotnet run, it's actually doing a build and then launching the resulting assembly through the .NET runtime. The trade-off here is a slight bit of overhead in project structure, but the payoff is massive: your build process is now codified in a file that can be checked into Git, ensuring that if it builds on my machine, it'll build on yours.

The gap between Debug and Release

One thing the "Run" button often hides is the difference between a Debug build and a Release build. When you're developing your DeadlineTracker, you're likely in Debug mode. The compiler leaves in a lot of extra metadata and skips certain optimizations so that you can set breakpoints and inspect variables. It's slower, but it's transparent.

But you would never ship a Debug build to a client. For that, you use dotnet publish -c Release. This tells the compiler to strip out the debugging fluff and aggressively optimize the IL code for performance. If you've ever wondered why your app feels sluggish during development but screams once it's deployed, this is why. The "naive" developer just copies the bin/Debug folder to the server; the professional uses a publish profile to create a clean, optimized package.




📋 Practical Task

Building and Analyzing the DeadlineTracker Binary

In this exercise, you will move away from the IDE's "Run" button to manually manage the build lifecycle of a project.

  1. Create a new console project named DeadlineTracker. Inside Program.cs, write a small program that subtracts the current date (DateTime.Now) from a hardcoded future date to print the remaining days.
  2. Open your terminal/command prompt and navigate to the project folder.
  3. Run dotnet build. Navigate into the bin/Debug/netX.X/ folder (where X.X is your version) and locate the DeadlineTracker.dll file.
  4. Now, execute the command dotnet publish -c Release.
  5. Locate the bin/Release/netX.X/publish/ folder. Compare the contents of the publish folder with the Debug folder.
  6. Identify which files are present in the Release publish folder that were not in the Debug folder, and note the difference in the .pdb files (symbol files) between the two environments.
Rating
0 0

There are no comments for now.

to be the first to leave a comment.