LearnAI ToolsCareerPractice BuildsPlayContact
Lesson 515 min read

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 HelloWorld
cd HelloWorld

This 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.

Fun Fact

"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

Program.cs
Console.WriteLine("Hello, World!");
Top-Level Statements

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.

HelloWorld.csproj
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>
SettingMeaning
OutputTypeExe means this builds to a runnable program (vs. Library for a reusable DLL).
TargetFrameworkWhich .NET version this project builds against — net8.0 here.
ImplicitUsingsAutomatically adds common using statements (like System) so you don't have to write them by hand.
NullableEnables nullable reference type warnings — the compiler helps catch potential null-reference bugs, covered in depth later in this course.
Notice How Small This Is

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 run
Output

Click 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 step

dotnet 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 run

Modifying the Program

Let's make it slightly more interesting by asking for the user's name:

Program.cs
Console.Write("What's your name? ");
string? name = Console.ReadLine();
Console.WriteLine($"Hello, {name}! Welcome to C#.");
Example Output

Click Run to see what this code prints.

A small but meaningful variation: what if the user just presses Enter without typing anything?

Program.cs
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#.");
}
A Preview of What's Coming

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.

A .gitignore entry every .NET project should have
bin/
obj/

Common Beginner Mistakes

Committing the bin/ and obj/ folders to Git

These are pure build output, regenerated automatically — committing them bloats your repository and can cause confusing conflicts between different developers' local builds.

Manually deleting the .csproj file "to start clean"

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.

Forgetting Console.ReadLine() can return null

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.

Next Lesson →

Program Structure