Your First C# Program
Create, run, and understand your first C# console application using the dotnet CLI.
Creating a New Project
The `dotnet` CLI can scaffold an entire working project structure for you from a template, so you never have to hand-create configuration files from scratch. Run this in an empty folder:
dotnet new console -o HelloWorldcd HelloWorldThis creates a project folder containing a `.csproj` file (project configuration) and a `Program.cs` file (your actual code) — the two files every console project needs at minimum.
"Hello, World!" as the traditional first program dates back to a 1972 internal Bell Labs memo by Brian Kernighan, and was popularized by the 1978 book "The C Programming Language" — over 50 years later, it remains the near-universal first example across virtually every programming language ever created, C# included.
Understanding the Files
Console.WriteLine("Hello, World!");Since C# 9 (2020), a simple program like this doesn't need an explicit namespace, class, or Main() method — the compiler generates that boilerplate for you automatically behind the scenes. This is called "top-level statements", and it is exactly what dotnet new console generates by default today.
Inside the .csproj File
The .csproj (C# project) file is an XML file describing how to build your project — its target framework version, output type, and any package dependencies. It is worth actually opening and reading, since you will edit it directly many times throughout real projects.
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <OutputType>Exe</OutputType> <TargetFramework>net8.0</TargetFramework> <ImplicitUsings>enable</ImplicitUsings> <Nullable>enable</Nullable> </PropertyGroup>
</Project>| Setting | Meaning |
|---|---|
| OutputType | Exe means this builds to a runnable program (vs. Library for a reusable DLL). |
| TargetFramework | Which .NET version this project builds against — net8.0 here. |
| ImplicitUsings | Automatically adds common using statements (like System) so you don't have to write them by hand. |
| Nullable | Enables nullable reference type warnings — the compiler helps catch potential null-reference bugs, covered in depth later in this course. |
Compare this to build configuration files in some other ecosystems — a default .NET console project's entire build configuration fits in about ten lines of XML, with almost everything else handled by convention.
Running the Program
dotnet runClick Run to see what this code prints.
Behind the scenes, dotnet run actually performs two steps for you in sequence: it first builds your project (compiling .cs files into CIL, as covered in the introduction lesson), then immediately executes the resulting output. You can run these two steps separately if you only want to compile without running.
dotnet build # compiles only, produces files in bin/dotnet run # compiles AND runs in one stepdotnet watch: Auto-Restart on Save
For a tighter feedback loop while learning, dotnet watch run automatically rebuilds and reruns your program every time you save a change to a source file — similar in spirit to "hot reload" tools in web development.
dotnet watch runModifying the Program
Let's make it slightly more interesting by asking for the user's name:
Console.Write("What's your name? ");string? name = Console.ReadLine();Console.WriteLine($"Hello, {name}! Welcome to C#.");Click Run to see what this code prints.
A small but meaningful variation: what if the user just presses Enter without typing anything?
Console.Write("What's your name? ");string? name = Console.ReadLine();
if (string.IsNullOrWhiteSpace(name)){ Console.WriteLine("Hello, mysterious stranger!");}else{ Console.WriteLine($"Hello, {name}! Welcome to C#.");}That if/else block and the string.IsNullOrWhiteSpace() helper method are both topics covered fully in upcoming lessons — for now, just notice that C# reads almost like plain English once you know its vocabulary.
The bin and obj Folders
After running dotnet build or dotnet run, you'll notice two new folders appear: bin/ (containing your actual compiled, runnable output) and obj/ (intermediate build artifacts MSBuild uses internally). Neither should ever be manually edited or committed to source control — they are entirely regenerated from your source files on every build.
bin/obj/Common Beginner Mistakes
These are pure build output, regenerated automatically — committing them bloats your repository and can cause confusing conflicts between different developers' local builds.
You almost never need to do this — if something feels broken, deleting just bin/ and obj/ and rebuilding usually resolves stale build state without touching your actual project configuration.
It returns null specifically when the input stream has been closed/redirected — this is exactly why the variable is typed string? (nullable), a detail covered fully in the nullable types lesson.
FAQs
Not for simple programs anymore — top-level statements handle it automatically. Larger projects (like ASP.NET Core apps) often still show an explicit entry point structure in generated templates, though the underlying mechanism is the same.
It marks the variable as nullable, meaning it is explicitly allowed to hold null — you'll learn about this in full detail in the Nullable Types lesson later in the course.
Yes — the file name itself doesn't matter to the compiler; Program.cs is simply the CLI's default convention for a new console project's entry point.
dotnet run rebuilds first if anything changed, then runs; running the compiled output directly (e.g. dotnet bin/Debug/net8.0/HelloWorld.dll) skips the rebuild step, useful once you know your code hasn't changed since the last build.
Key Takeaways
- dotnet new console scaffolds a new console app with a .csproj and a Program.cs file.
- dotnet run compiles and runs your project in one step; dotnet build only compiles.
- Modern C# uses top-level statements, removing namespace/class/Main boilerplate for simple programs.
- The bin/ and obj/ folders are pure build output — never edit or commit them.
Summary
You've now created, run, and modified a real C# program, and peeked inside the .csproj file that configures how it builds. Next, you'll zoom out and understand the fuller structure a C# program can take, including namespaces and classes explicitly.