Menu

C# Hello World: Main, Console.WriteLine und ReadLine

Dein erstes C#-Programm Zeile für Zeile: die Main-Methode, Console.WriteLine und Write, Eingaben lesen mit Console.ReadLine, Kommentare, ein Projekt mit der dotnet CLI anlegen und ausführen sowie Top-Level-Anweisungen.

Diese Seite enthält ausführbare Editoren - bearbeiten, ausführen und Ausgabe sofort sehen.

Das klassische erste Programm gibt eine Textzeile aus. In C# sieht es so aus:

Ausgabe:

Hello, World!

Zeile für Zeile

  • using System; erlaubt dir, Console statt des vollen Namens System.Console zu schreiben. Console ist eine Klasse im Namespace System (siehe Namespaces und using).
  • class Program deklariert eine Klasse. Jeder C#-Code steht in einem Typ; der Name Program ist eine Konvention, keine Pflicht.
  • static void Main() ist der Einstiegspunkt. Beim Programmstart sucht die Runtime nach einer statischen Methode namens Main und ruft sie auf. static bedeutet, dass sie zur Klasse selbst gehört, also muss vorher kein Objekt erzeugt werden. void bedeutet, dass sie nichts zurückgibt.
  • Console.WriteLine("Hello, World!"); ruft die Methode WriteLine mit einem String-Argument auf. Jede Anweisung endet mit einem Semikolon.
  • Die geschweiften Klammern { } markieren den Rumpf der Klasse und der Methode.

C# unterscheidet Groß- und Kleinschreibung. console.writeline und main sind andere Namen als Console.WriteLine und Main, und keiner von beiden existiert.

Console.WriteLine vs. Console.Write

WriteLine hängt nach dem Text einen Zeilenumbruch an. Write tut das nicht, die nächste Ausgabe geht also in derselben Zeile weiter. Beide akzeptieren jeden Typ, nicht nur Strings: Zahlen, Booleans und Objekte werden mit ihrer Methode ToString() umgewandelt.

Ausgabe:

Loading.. done
42
True

Item: coffee
coffee costs 3.20
coffee costs 3.20

Beachte, dass true als True ausgegeben wird: Das liefert bool.ToString(). Die Form $"...", String-Interpolation genannt, wirst du am häufigsten verwenden; Formatcodes wie :F2 findest du unter String-Interpolation.

Eingaben lesen mit Console.ReadLine

Console.ReadLine() wartet, bis der Benutzer eine Zeile eingibt und Enter drückt, und gibt diese Zeile dann als string ohne Zeilenumbruch zurück. Am Ende der Eingabe (zum Beispiel wenn die Eingabe aus einer Datei umgeleitet wird, die zu Ende ist) gibt sie null zurück.

Ausgabe:

What is your name? How old are you? 
Hi Maya, next year you will be 28.

Wenn du das in einem Terminal ausführst, erscheint der eingegebene Text nach jeder Aufforderung. In der Ausgabe oben steht kein eingegebener Text, weil die Eingabe umgeleitet (per Pipe übergeben) statt getippt wurde, daher erscheint nur, was das Programm selbst schreibt.

ReadLine gibt immer Text zurück. Um den Wert als Zahl zu verwenden, musst du ihn umwandeln. int.Parse(text) wirft eine FormatException, wenn der Text keine Zahl ist; int.TryParse gibt stattdessen false zurück und ist deshalb die richtige Wahl für Benutzereingaben. Die Details stehen unter Typumwandlung.

Zwei verwandte Methoden: Console.Read() gibt das nächste Zeichen als int-Code zurück, und Console.ReadKey() liest einen einzelnen Tastendruck, ohne auf Enter zu warten (das funktioniert nur in einem interaktiven Terminal).

Die anderen Formen der Main-Methode

Main kann die Kommandozeilenargumente entgegennehmen und einen Exit-Code zurückgeben. All das sind gültige Einstiegspunkte:

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

Ein zurückgegebenes int wird zum Exit-Code des Prozesses, den Skripte und CI-Systeme lesen, um zu entscheiden, ob das Programm erfolgreich war (0 bedeutet per Konvention Erfolg).

Ausgabe:

Got 0 argument(s)

Starte es mit dotnet run -- apples pears, dann enthält args die Werte "apples" und "pears". Das -- trennt die Argumente für dein Programm von den Argumenten für das Tool dotnet.

Kommentare

C# kennt drei Arten von Kommentaren. Der Compiler ignoriert sie alle.

// 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;

Nimm // für Notizen im Code. ///-Kommentare gehören an Typen und öffentliche Member; die IDE zeigt sie an, wenn du über einen Aufruf fährst, und der Compiler kann sie für Dokumentationstools in eine XML-Datei exportieren.

Ein Projekt mit dotnet anlegen und ausführen

Auf deinem eigenen Rechner installierst du das .NET SDK von dotnet.microsoft.com und führst dann aus:

dotnet new console -o HelloApp
cd HelloApp
dotnet run
Hello, World!

dotnet new console legt zwei Dateien an: HelloApp.csproj (die Projektdatei: Zielframework, Einstellungen, Paketreferenzen) und Program.cs. dotnet run kompiliert das Projekt und führt es aus. dotnet build kompiliert, ohne auszuführen, und schreibt die Ausgabe nach bin/Debug/net8.0/ (der Ordnername richtet sich nach deinem Zielframework).

Top-Level-Anweisungen (C# 9 und neuer)

Öffne die erzeugte Program.cs, und du findest das hier und sonst nichts:

// See https://aka.ms/new-console-template for more information
Console.WriteLine("Hello, World!");

Das ist ein Programm mit Top-Level-Anweisungen, einem Feature von C# 9. Der Compiler erzeugt die Klasse Program und die Methode Main um deine Anweisungen herum. Auch using System; fehlt, weil Projekte ab .NET 6 implizite Usings aktivieren: Häufige Namespaces wie System, System.IO, System.Linq und System.Collections.Generic werden für das ganze Projekt importiert.

Top-Level-Programme können trotzdem args lesen, await verwenden und mit return einen Exit-Code zurückgeben:

// 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;

Nur eine Datei pro Projekt darf Top-Level-Anweisungen enthalten, und Typen (Klassen, Records) müssen danach kommen. Die Annotation string? ist ein Nullable-Referenztyp (C# 8) und steht dort, weil ReadLine null zurückgeben kann. Die explizite Form class Program, die in den Beispielen auf dieser Seite verwendet wird, ist gleichwertig und begegnet dir in älterem Code und in den meisten Unity-Skripten, also lohnt es sich, beide lesen zu können. Übergib --use-program-main an dotnet new console, wenn du in neuen Projekten die explizite Form bevorzugst.

Fehler, die dir zuerst begegnen

  • CS1002: ; expected. Einer Anweisung fehlt das Semikolon. Der Fehler wird am Ende der Zeile gemeldet, in der es fehlt.
  • CS0103: The name 'console' does not exist in the current context. Falsche Groß- und Kleinschreibung oder ein fehlendes using System; in einem Projekt ohne implizite Usings.
  • CS5001: Program does not contain a static 'Main' method suitable for an entry point. Main ist falsch geschrieben, nicht static oder hat eine nicht unterstützte Signatur.
  • CS0017: Program has more than one entry point defined. Zwei Klassen haben jeweils ein Main. Behalte eines oder wähle eines mit der Einstellung StartupObject in der .csproj.
  • Das Fenster schließt sich sofort. Wenn eine Konsolen-App per Doppelklick gestartet wird, schließt sich das Fenster, sobald Main zurückkehrt. Starte sie aus einem Terminal oder füge beim Testen Console.ReadKey(); am Ende hinzu.

Häufig gestellte Fragen

Wie schreibt man Hello World in C#?

Schreibe Console.WriteLine("Hello, World!"); in eine Methode static void Main() einer Klasse, mit using System; am Anfang der Datei. In einem Projekt, das mit dotnet new console unter .NET 6 oder neuer erstellt wurde, kann die ganze Datei aus genau dieser einen Zeile bestehen, weil Top-Level-Anweisungen die Klasse und Main für dich erzeugen.

Was ist die Main-Methode in C#?

Main ist der Einstiegspunkt: die Methode, die die Runtime beim Programmstart aufruft. Sie muss static sein, kann void oder int (den Exit-Code) zurückgeben und einen Parameter string[] args mit den Kommandozeilenargumenten annehmen. Ein Programm braucht genau eine.

Was ist der Unterschied zwischen Console.Write und Console.WriteLine?

Console.WriteLine schreibt den Text und danach einen Zeilenumbruch, die nächste Ausgabe beginnt also in einer neuen Zeile. Console.Write schreibt nur den Text, die nächste Ausgabe geht in derselben Zeile weiter. Console.WriteLine() ohne Argumente gibt eine leere Zeile aus.

Wie lese ich Benutzereingaben in C#?

Console.ReadLine() liest eine Textzeile und gibt sie als string zurück (ohne Zeilenumbruch), oder null, wenn keine Eingabe mehr kommt. Für eine Zahl wandelst du den String um: int.TryParse(Console.ReadLine(), out int n) gibt false zurück, statt abzustürzen, wenn der Text keine Zahl ist.

Wie führe ich ein C#-Programm auf der Kommandozeile aus?

Installiere das .NET SDK, dann legst du mit dotnet new console -o HelloApp ein Projekt an, wechselst mit cd HelloApp hinein und baust und startest es mit dotnet run. dotnet build kompiliert nur und legt die Ausgabe in bin/Debug/net8.0/ ab (oder im Ordner der Version, auf die du zielst).

Coddy programming languages illustration

Lerne mit Coddy zu programmieren

LOS GEHT'S