The classic first program prints one line of text. In C# it looks like this:
Output:
Hello, World!
Line by line
using System;lets you writeConsoleinstead of the full nameSystem.Console.Consoleis a class in theSystemnamespace (see namespaces and using).class Programdeclares a class. All C# code lives inside a type; the nameProgramis a convention, not a requirement.static void Main()is the entry point. When the program starts, the runtime looks for a static method namedMainand calls it.staticmeans it belongs to the class itself, so no object has to be created first.voidmeans it returns nothing.Console.WriteLine("Hello, World!");calls theWriteLinemethod with a string argument. Every statement ends with a semicolon.- The braces
{ }mark the body of the class and of the method.
C# is case sensitive. console.writeline and main are different names from Console.WriteLine and Main, and neither exists.
Console.WriteLine vs Console.Write
WriteLine adds a newline after the text. Write does not, so the next output continues on the same line. Both accept any type, not only strings: numbers, booleans and objects are converted with their ToString() method.
Output:
Loading.. done
42
True
Item: coffee
coffee costs 3.20
coffee costs 3.20
Notice that true prints as True: that is what bool.ToString() returns. The $"..." form, called string interpolation, is the one you will use most; see string interpolation for the format codes like :F2.
Reading input with Console.ReadLine
Console.ReadLine() waits for the user to type a line and press Enter, then returns that line as a string without the newline. At the end of input (for example when input is redirected from a file that has run out) it returns null.
Output:
What is your name? How old are you?
Hi Maya, next year you will be 28.
When you run this in a terminal, the text you type appears after each prompt. The output above has no typed text in it because the input was redirected (piped in) rather than typed, so only what the program itself writes shows up.
ReadLine always returns text. To use the value as a number you have to convert it. int.Parse(text) throws a FormatException when the text is not a number; int.TryParse returns false instead, which is why it is the right choice for user input. The details are in type conversion.
Two related methods: Console.Read() returns the next character as an int code, and Console.ReadKey() reads a single key press without waiting for Enter (it only works in an interactive terminal).
The Main method's other forms
Main can take the command-line arguments and can return an exit code. These are all valid entry points:
static void Main()
static void Main(string[] args)
static int Main()
static int Main(string[] args)
static async Task Main() // C# 7.1 and later
static async Task<int> Main(string[] args) // C# 7.1 and later
A returned int becomes the process exit code, which scripts and CI systems read to decide whether the program succeeded (0 means success by convention).
Output:
Got 0 argument(s)
Run it with dotnet run -- apples pears and args holds "apples" and "pears". The -- separates arguments for your program from arguments for the dotnet tool.
Comments
C# has three kinds of comments. The compiler ignores all of them.
// A single-line comment runs to the end of the line.
/* A block comment
can span several lines. */
/// <summary>
/// An XML documentation comment. Editors show it as the tooltip for the method.
/// </summary>
static decimal ApplyDiscount(decimal price) => price * 0.9m;
Use // for notes inside code. /// comments go on types and public members; the IDE displays them when you hover over a call, and the compiler can export them to an XML file for documentation tools.
Creating and running a project with dotnet
On your own machine, install the .NET SDK from dotnet.microsoft.com, then:
dotnet new console -o HelloApp
cd HelloApp
dotnet run
Hello, World!
dotnet new console creates two files: HelloApp.csproj (the project file: target framework, settings, package references) and Program.cs. dotnet run compiles the project and runs it. dotnet build compiles without running and writes the output to bin/Debug/net8.0/ (the folder name follows your target framework).
Top-level statements (C# 9 and later)
Open the generated Program.cs and you will find this, and nothing else:
// See https://aka.ms/new-console-template for more information
Console.WriteLine("Hello, World!");
This is a top-level statements program, a C# 9 feature. The compiler generates the Program class and the Main method around your statements. using System; is also missing because .NET 6 and later projects enable implicit usings: common namespaces such as System, System.IO, System.Linq and System.Collections.Generic are imported for the whole project.
Top-level programs can still read args, use await, and return an exit code:
// C# 9 and later: the whole Program.cs
Console.Write("Name: ");
string? name = Console.ReadLine();
Console.WriteLine($"Hello, {name}! You passed {args.Length} arguments.");
return 0;
Only one file per project can contain top-level statements, and types (classes, records) must come after them. The string? annotation is a nullable reference type (C# 8), and it is there because ReadLine can return null. The explicit class Program form used in the examples on this page is equivalent and is what you will see in older code and in most Unity scripts, so it is worth being able to read both. Pass --use-program-main to dotnet new console if you prefer the explicit form in new projects.
Errors you will see first
- CS1002: ; expected. A statement is missing its semicolon. The error is reported at the end of the line that is missing it.
- CS0103: The name 'console' does not exist in the current context. Wrong capitalization, or a missing
using System;in a project without implicit usings. - CS5001: Program does not contain a static 'Main' method suitable for an entry point.
Mainis misspelled, notstatic, or has an unsupported signature. - CS0017: Program has more than one entry point defined. Two classes each have a
Main. Keep one, or pick one with theStartupObjectsetting in the.csproj. - The window closes immediately. When a console app is started by double-clicking, the window closes when
Mainreturns. Run it from a terminal, or addConsole.ReadKey();at the end while testing.
Frequently Asked Questions
How do you write Hello World in C#?
Put Console.WriteLine("Hello, World!"); inside a static void Main() method of a class, with using System; at the top. In a project created by dotnet new console on .NET 6 or later, the whole file can be just that one line, because top-level statements generate the class and Main for you.
What is the Main method in C#?
Main is the entry point: the method the runtime calls when the program starts. It must be static, can return void or int (the exit code), and can take a string[] args parameter with the command-line arguments. A program needs exactly one.
What is the difference between Console.Write and Console.WriteLine?
Console.WriteLine writes the text followed by a newline, so the next output starts on a new line. Console.Write writes the text only, so the next output continues on the same line. Console.WriteLine() with no arguments prints an empty line.
How do I read user input in C#?
Console.ReadLine() reads one line of text and returns it as a string (without the newline), or null when there is no more input. To get a number, convert the string: int.TryParse(Console.ReadLine(), out int n) returns false instead of crashing when the text is not a number.
How do I run a C# program from the command line?
Install the .NET SDK, then run dotnet new console -o HelloApp to create a project, cd HelloApp, and dotnet run to build and run it. dotnet build only compiles, and puts the output in bin/Debug/net8.0/ (or the version you target).