Projects and the dotnet CLI
Single-file programs are perfect for learning and small scripts. Real applications are organised as projects: a folder with a .csproj file that describes how to build the code, which can span many source files and use packages. This lesson shows how to create, build and run projects with the dotnet command, and how the Main method works.
Creating a console project
dotnet new console -o Hello cd Hello dotnet run
Hello, World!
dotnet new console creates a project from the "Console App" template; -o Hello puts it in a new folder called Hello. The folder contains two files:
Console.WriteLine("Hello, World!");
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <OutputType>Exe</OutputType> <TargetFramework>net10.0</TargetFramework> <ImplicitUsings>enable</ImplicitUsings> <Nullable>enable</Nullable> </PropertyGroup> </Project>
Reading the project file
| Setting | Meaning |
|---|---|
OutputType Exe | Build a runnable program. Leave it out for a class library that other projects use. |
TargetFramework net10.0 | The .NET version the program runs on. It also decides the default C# version: .NET 10 means C# 14. |
ImplicitUsings | Automatically imports common namespaces such as System, System.IO, System.Linq and System.Collections.Generic, so you can write Console and List without using lines. |
Nullable | Turns on nullable reference type warnings (lesson 43). |
Single-file apps get the same defaults automatically, which is why Console.WriteLine worked in the last lesson with no setup.
The most useful commands
| Command | What it does |
|---|---|
dotnet new list | Show available templates (console, classlib, web, xunit, …). |
dotnet build | Compile the project into bin/Debug/net10.0/. |
dotnet run | Build if anything changed, then run. |
dotnet run -- a b | Run, passing a and b as command-line arguments to your program. |
dotnet watch | Rebuild and rerun automatically whenever you save a file. |
dotnet test | Run a test project (lesson 60). |
dotnet add package Name | Add a NuGet package (lesson 60). |
dotnet publish -c Release | Produce an optimised build ready to deploy. |
dotnet clean | Delete build outputs. |
After dotnet build, the output folder holds Hello.dll (your compiled IL), a native launcher called Hello (Hello.exe on Windows) and a few configuration files. The obj folder holds intermediate files. Neither folder belongs in version control.
The Main method
Top-level statements are a shortcut. Underneath, every C# program starts from a method called Main, and you can write it out yourself. This is the style you'll see in older code and many tutorials:
namespace Hello; class Program { static void Main(string[] args) { Console.WriteLine("Hello from Main!"); Console.WriteLine($"You passed {args.Length} argument(s)."); } }
Hello from Main! You passed 0 argument(s).
The pieces — namespace, class, static, void and parameters — are covered in later lessons. For now, know that both styles produce the same kind of program, and a project can contain only one of them. This course uses top-level statements for short examples.
Command-line arguments
With top-level statements, the arguments are available in a ready-made variable called args, an array of strings:
Console.WriteLine($"Arguments: {args.Length}"); foreach (string arg in args) { Console.WriteLine($"Hello, {arg}!"); }
dotnet run Program.cs -- Ada Linus
Arguments: 2 Hello, Ada! Hello, Linus!
Everything after -- is passed to your program instead of being read by dotnet itself.
From one file to a project
When a single-file program grows, convert it into a project:
dotnet project convert hello.cs
This creates a hello folder with a hello.csproj and a copy of your code. A single file can also carry project settings and package references through #: directives at the top, which the conversion turns into project-file entries:
#:property LangVersion=preview #:package Humanizer@2.14.1
You'll use #:package in lesson 60.
Which should you use?
- Single file (
dotnet run app.cs): learning, experiments, small utility scripts. - Project (
dotnet new): anything with several files, tests, or that you'll ship or maintain — and every web, desktop or library project.
Try it yourself
Run this with a few arguments, for example dotnet run Program.cs -- red green blue.
No arguments. Try: dotnet run Program.cs -- one two