C# Grundlagen

6 Kernkonzepte
Die wichtigsten Grundlagen der C#-Programmierung: Syntax · Datentypen · Kontrollstrukturen · OOP · Collections · LINQ C# ist eine moderne, objektorientierte Sprache für die .NET-Plattform. Diese Grundlagen sind essenziell für die Entwicklung von Anwendungen, Spielen und Webdiensten.

Syntax – Grundstruktur einer C#-Anwendung

using · namespace · class · Main
using System; namespace MeinProgramm { class Program { static void Main(string[] args) { Console.WriteLine("Hallo Welt!"); } } }

C#-Programme bestehen aus Namespaces, Klassen und Methoden. Die Main()-Methode ist der Einstiegspunkt. Jede Anweisung endet mit einem Semikolon (;).

Wichtige Syntax-Elemente

Element Beschreibung
using Importiert Namespaces (z.B. System, System.IO)
namespace Organisiert Code in logischen Gruppen
class Definiert einen neuen Typ (Blaupause für Objekte)
static void Main() Einstiegspunkt der Anwendung
Console.WriteLine() Ausgabe auf die Konsole
Console.ReadLine() Eingabe von der Konsole
// Kommentar Einzeiliger Kommentar
/* */ Mehrzeiliger Kommentar
/// XML-Dokumentationskommentar
Beispiele
using System;
using System.Collections.Generic;
namespace Beispiele {
class Program {
/// <summary>Hauptmethode</summary>
static void Main(string[] args) {
// Ausgabe
Console.Write("Ihr Name: ");
string name = Console.ReadLine();
Console.WriteLine($"Hallo {name}!");
}
}
}
Tipp: Verwenden Sie String-Interpolation mit $"Text {variable}" für lesbare String-Formatierung – das ist moderner als string.Format().

Datentypen – Wertetypen & Referenztypen

int · double · string · bool · var
int zahl = 42; // Ganzzahl (Wertetyp) double pi = 3.14159; // Gleitkommazahl (Wertetyp) string name = "Anna"; // Text (Referenztyp) bool istWahr = true; // Wahrheitswert (Wertetyp) var x = 10; // Typableitung (int)

Datentypen definieren die Art der Daten, die eine Variable speichern kann. C# unterscheidet zwischen Wertetypen (Stack) und Referenztypen (Heap).

Die wichtigsten Datentypen

Typ Kategorie Größe Bereich Beispiel
int Wertetyp 4 Byte -2.147.483.648 bis 2.147.483.647 42
long Wertetyp 8 Byte -9.223.372.036.854.775.808 bis ... 42L
float Wertetyp 4 Byte ±3.4e−38 bis ±3.4e+38 3.14f
double Wertetyp 8 Byte ±5.0e−324 bis ±1.7e+308 3.14159
decimal Wertetyp 16 Byte ±1.0e−28 bis ±7.9e+28 (28 Stellen) 99.99m
char Wertetyp 2 Byte Unicode-Zeichen 'A'
bool Wertetyp 1 Byte true / false true
string Referenztyp variabel Text "Hallo"
object Referenztyp variabel Beliebiger Typ new object()
Beispiele
// Wertetypen (Stack)
int a = 10;
int b = a; // Kopie (unabhängig)
b = 20; // a bleibt 10
// Referenztypen (Heap)
string s1 = "Hallo";
string s2 = s1; // Referenz (gleiches Objekt)
// String ist unveränderlich → s1 bleibt "Hallo"
// Nullable-Typen
int? nullableInt = null;
double? nullableDouble = 3.14;
// Null-Coalescing-Operator
int ergebnis = nullableInt ?? 0;
Tipp: Verwenden Sie decimal für Geldbeträge und präzise Berechnungen. Verwenden Sie double für wissenschaftliche Berechnungen. var ist nützlich, wenn der Typ offensichtlich ist.

Kontrollstrukturen – if, switch, for, foreach, while

if · else · switch · for · foreach · while
if (x > 0) { Console.WriteLine("Positiv"); } else if (x < 0) { Console.WriteLine("Negativ"); } else { Console.WriteLine("Null"); }

Kontrollstrukturen steuern den Programmablauf – Bedingungen, Schleifen und Fallunterscheidungen. C# bietet sowohl klassische als auch moderne Konstrukte.

Die wichtigsten Kontrollstrukturen

Struktur Beschreibung Beispiel
if / else Bedingte Ausführung if (x > 0) { ... }
switch Fallunterscheidung switch (x) { case 1: ... }
for Zählergesteuerte Schleife for (int i = 0; i < 10; i++) { ... }
foreach Iteration über Collections foreach (var item in list) { ... }
while Kopfgesteuerte Schleife while (x < 10) { ... }
do-while Fußgesteuerte Schleife do { ... } while (x < 10);
break Schleife beenden break;
continue Schleifendurchlauf überspringen continue;
return Methode beenden return value;
Beispiele
// if-else mit Pattern Matching
object obj = 42;
if (obj is int i) {
Console.WriteLine($"Zahl: {i}");
}
// switch mit Pattern Matching (C# 8+)
switch (x) {
case 0: Console.WriteLine("Null"); break;
case > 0: Console.WriteLine("Positiv"); break;
case < 0: Console.WriteLine("Negativ"); break;
}
// foreach über Liste
List<string> namen = new List<string> { "Anna", "Ben", "Clara" };
foreach (var name in namen) {
Console.WriteLine(name);
}
Tipp: Verwenden Sie foreach für Iterationen über Collections – es ist sicherer und lesbarer als for, wenn Sie nur lesend zugreifen.

OOP – Klassen, Vererbung, Polymorphie

class · new · : · override · virtual
// Klasse definieren class Person { public string Name { get; set; } public int Alter { get; set; } public virtual void Vorstellen() { Console.WriteLine($"Ich bin {Name}"); } } // Vererbung class Student : Person { public string Matrikelnummer { get; set; } public override void Vorstellen() { Console.WriteLine($"Ich bin Student {Name}"); } }

Objektorientierte Programmierung in C# verwendet Klassen, Vererbung, Polymorphie und Kapselung. C# unterstützt moderne OOP-Konzepte wie Properties, Auto-Properties und Records.

Beispiele
// Auto-Properties (seit C# 3.0)
class Produkt {
public int Id { get; set; }
public string Name { get; set; }
public decimal Preis { get; set; }
}
// Konstruktor
class Kunde {
public string Name { get; }
public Kunde(string name) { Name = name; }
}
// Objekterstellung
var produkt = new Produkt { Id = 1, Name = "Laptop", Preis = 999.99m };
// Records (C# 9+) – unveränderliche Datencontainer
public record PersonRecord(string Name, int Alter);
var person = new PersonRecord("Anna", 30);
Tipp: Verwenden Sie Records (C# 9+) für unveränderliche Datencontainer. Sie bieten automatisch Wertgleichheit und sind ideal für DTOs (Data Transfer Objects).

Collections – List, Dictionary, Array, HashSet

List<T> · Dictionary<K,V> · Array · HashSet<T>
List<string> namen = new List<string>(); namen.Add("Anna"); var dict = new Dictionary<string, int>(); dict.Add("Alter", 30); int[] zahlen = { 1, 2, 3 };

Collections sind Datenstrukturen für die Speicherung und Verwaltung von Elementgruppen. Die generischen Collections im System.Collections.Generic-Namespace sind typsicher und leistungsfähig.

Die wichtigsten Collections

Collection Beschreibung Beispiel
List<T> Dynamisches Array (indizierter Zugriff) new List<string>()
Dictionary<TKey, TValue> Schlüssel-Wert-Paare (schneller Zugriff) new Dictionary<string, int>()
T[] Festes Array int[] zahlen = new int[10]
HashSet<T> Eindeutige Elemente (ungeordnet) new HashSet<string>()
Queue<T> FIFO (First In, First Out) new Queue<string>()
Stack<T> LIFO (Last In, First Out) new Stack<string>()
IEnumerable<T> Interface für Iteration (LINQ) IEnumerable<int> sequence = ...
Beispiele
// List
var names = new List<string> { "Anna", "Ben", "Clara" };
names.Add("David");
names.Remove("Ben");
var first = names[0];
// Dictionary
var user = new Dictionary<string, string>();
user["name"] = "Anna";
user.Add("email", "anna@example.com");
var email = user.GetValueOrDefault("email");
// HashSet (eindeutige Werte)
var unique = new HashSet<int> { 1, 2, 3, 2 };
Console.WriteLine(unique.Count); // 3 (2 ist doppelt)
Tipp: Verwenden Sie List<T> für dynamische Sequenzen, Dictionary<TKey, TValue> für schnelle Schlüsselsuchen und HashSet<T> für eindeutige Werte.

LINQ – Abfragen auf Collections

Where · Select · OrderBy · GroupBy · First
// Query-Syntax var ergebnis = from x in zahlen where x > 5 orderby x descending select x * 2; // Method-Syntax (Fluent API) var ergebnis2 = zahlen.Where(x => x > 5) .OrderByDescending(x => x) .Select(x => x * 2);

LINQ (Language Integrated Query) ermöglicht deklarative Abfragen auf Collections, Datenbanken und XML. Es gibt zwei Syntaxvarianten: Query-Syntax und Method-Syntax.

Wichtige LINQ-Operationen

Operation Beschreibung Beispiel
Where Filtert Elemente nach Bedingung .Where(x => x > 0)
Select Projiziert Elemente (Transformiert) .Select(x => x * 2)
OrderBy / OrderByDescending Sortiert Elemente .OrderBy(x => x.Name)
GroupBy Gruppiert Elemente nach Schlüssel .GroupBy(x => x.Kategorie)
First / FirstOrDefault Erstes Element (oder Default) .FirstOrDefault(x => x.Id == 1)
Any Prüft, ob Elemente existieren .Any(x => x > 0)
Count Zählt Elemente .Count(x => x > 0)
Sum / Average Summe / Durchschnitt .Sum(x => x.Preis)
Beispiele
// Daten
var produkte = new List<Produkt> {
new Produkt { Id = 1, Name = "Laptop", Preis = 999.99m, Kategorie = "Elektronik" },
new Produkt { Id = 2, Name = "Tisch", Preis = 199.99m, Kategorie = "Möbel" }
};
// Query-Syntax
var teureProdukte = from p in produkte
where p.Preis > 200
orderby p.Preis descending
select p;
// Method-Syntax mit Gruppierung
var gruppen = produkte.GroupBy(p => p.Kategorie)
.Select(g => new {
Kategorie = g.Key,
Anzahl = g.Count(),
Durchschnittspreis = g.Average(p => p.Preis)
});
// Erweiterungsmethoden
var erster = produkte.FirstOrDefault(p => p.Id == 1);
bool existiert = produkte.Any(p => p.Preis > 1000);
var gesamt = produkte.Sum(p => p.Preis);
Tipp: Method-Syntax (Fluent API) ist flexibler und wird in der Praxis häufiger verwendet. Query-Syntax ist lesbarer für komplexe Abfragen. Beide sind gleichwertig.

C# Grundlagen im Überblick

using Namespace importieren
System, System.IO
class Blaupause für Objekte
public, private, static
var Typableitung
Seit C# 3.0
LINQ Datenbankähnliche Abfragen
Where, Select, GroupBy
GC Garbage Collection
Automatische Speicherverwaltung
.NET Runtime & Frameworks
.NET Core, .NET 5+

Quick Summary

Main()
Programm-Einstieg
int
Datentypen
if
Kontrollstrukturen
class
OOP
List
Collections
LINQ
Abfragen
Console.WriteLine("Hallo"); · var list = new List<string>(); · var result = from x in data where x > 0 select x;