Kurse:Datentypen-C-Sharp
String
Grundlagen
- Deklaration
string name = "Alice";
string leer = string.Empty;
- Verkettung
string full = vorname + " " + nachname;
string interp = $"{vorname} {nachname}";
var builder = new StringBuilder().Append(vorname).Append(' ').Append(nachname).ToString();
Häufig genutzte Eigenschaften
- Length – Anzahl der UTF-16 Codeeinheiten (nicht zwingend Benutzer-grafeme)
Vergleich
string.Equals(a, b); // Ordinal, case-sensitiv
string.Equals(a, b, StringComparison.OrdinalIgnoreCase);
a.Equals(b, StringComparison.Ordinal);
a == b; // Wertvergleich
string.Compare(a, b, StringComparison.Ordinal);
Suchen
str.Contains("abc", StringComparison.Ordinal);
str.StartsWith("pre", StringComparison.OrdinalIgnoreCase);
str.EndsWith("suf", StringComparison.Ordinal);
str.IndexOf("x", StringComparison.Ordinal);
str.LastIndexOf('.');
Extrahieren
str.Substring(startIndex);
str.Substring(startIndex, length);
str[startIndex]; // einzelnes char
Teilstrings moderner (Span-Slicing)
ReadOnlySpan<char> span = str.AsSpan();
var teil = span.Slice(5, 3); // vermeidet Kopie
Aufteilen & Zusammenfügen
var parts = str.Split('.', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
string joined = string.Join(";", parts);
Trimmen
str.Trim(); // Whitespace
str.TrimStart();
str.TrimEnd();
str.Trim('0'); // spezifische Zeichen
Ersetzen
str.Replace("alt", "neu");
str.Replace('a', 'b');
Regex.Replace(str, "[0-9]+", "#");
Formatierung
string.Format("Wert: {0:N2}", value);
$"Wert: {value:N2}";
value.ToString("N2", CultureInfo.InvariantCulture);
Groß/Kleinschreibung
str.ToUpperInvariant();
str.ToLower(CultureInfo.CurrentCulture);
Einfügen & Entfernen
str.Insert(index, "XYZ");
str.Remove(startIndex);
str.Remove(startIndex, count);
Pad (Auffüllen)
"42".PadLeft(5, '0'); // 00042
"42".PadRight(5, '.'); // 42...
Zeichenprüfung
char.IsLetterOrDigit(ch);
char.IsWhiteSpace(ch);
Immutable Hinweis
Strings sind unveränderlich. Viele Operationen erzeugen neue Instanzen. Für viele Verkettungen: StringBuilder.
StringBuilder
var sb = new StringBuilder(capacity:256)
.Append("Zeile ").AppendLine("1")
.AppendFormat("Wert={0}", 123);
string result = sb.ToString();
Sicherheitsrelevante Vergleiche
CryptographicOperations.FixedTimeEquals(
MemoryMarshal.AsBytes("secret"u8),
MemoryMarshal.AsBytes(eingabe.AsSpan()));
Null / Empty / WhiteSpace
string.IsNullOrEmpty(str);
string.IsNullOrWhiteSpace(str);
Interpolated String Handler (Performance)
[InterpolatedStringHandler]
public ref struct LogHandler {
// eigener Handler für Logging
}
Raw String Literals (C# 11)
string json = """
{
"id": 1,
"name": "Alice"
}
""";
Escapes
string pfad = @"C:\Temp\log.txt";
string zeile = "Text\nNeue Zeile\tTab";
Normalisierung (Unicode)
string norm = str.Normalize(NormalizationForm.FormC);
Split vs Span
Für Hochleistung: str.AsSpan().Split(...) (ab .NET 8: MemoryExtensions.Split)
Zusammenfassung
Kurzliste: Length, Indexer, Substring, Contains, StartsWith, EndsWith, IndexOf, Split, Join, Trim*, Replace, Insert, Remove, PadLeft/Right, ToUpper*/ToLower*, Format/$-Interpolation, Equals/Compare, Normalize, StringBuilder.
Ganzzahlen: Operationen und wichtige Methoden
Basis-Typen
- sbyte / byte (8 Bit), short / ushort (16), int / uint (32), long / ulong (64)
- nint / nuint (plattformabhängig), BigInteger (beliebig groß, System.Numerics)
Deklaration & Literale
int a = 42;
long b = 1_000_000_000L;
uint c = 0u;
nint p = 123n;
int bin = 0b1010_1100;
int hex = 0xFF_A0;
Konvertierung / Casting
long l = a; // implizit (erweiternd)
int k = (int)l; // explizit (evtl. Datenverlust)
int parsed = int.Parse("123", CultureInfo.InvariantCulture);
if (int.TryParse("123", out var val)) { /* ok */ }
Rechenoperationen
int sum = x + y;
int diff = x - y;
int prod = x * y;
int quot = x / y; // ganzzahlig, Rest abgeschnitten
int mod = x % y;
int neg = -x;
Division: Ganzzahl vs Gleitkomma
int r1 = 5 / 2; // 2
double r2 = 5 / 2.0; // 2.5
Inkrement / Dekrement
i++;
++i;
i--;
Overflow-Kontrolle
checked {
int o = int.MaxValue;
// int p = o + 1; // OverflowException
}
unchecked {
int wrap = int.MaxValue + 1; // Wrap-around
}
bool ok = int.TryParse("9999999999", out _); // false wenn außerhalb Range
Vergleich & Relationen
bool eq = a == b;
bool ne = a != b;
bool lt = a < b;
bool between = x >= min && x <= max;
Bitoperationen
int and = flags & mask;
int or = flags | mask;
int xor = flags ^ mask;
int not = ~flags;
int shiftedL = value << 3;
int shiftedR = value >> 2;
bool has = (flags & mask) != 0;
BitHelpers (.NET)
int pop = System.Numerics.BitOperations.PopCount((uint)value);
int leading = BitOperations.LeadingZeroCount((uint)value);
int rot = BitOperations.RotateLeft(value, 5);
Math / Numerik
int abs = Math.Abs(v);
int clamped = Math.Clamp(v, 0, 100);
int max = Math.Max(a, b);
int min = Math.Min(a, b);
int sign = Math.Sign(v);
long pow2 = 1L << n;
Zufallszahlen
int r = Random.Shared.Next(0, 100); // 0..99
int rr = RandomNumberGenerator.GetInt32(0, 100); // kryptographisch
Parsing / Formatierung
int n = int.Parse("42");
if (int.TryParse("42", NumberStyles.Integer, CultureInfo.InvariantCulture, out var num)) {}
string s1 = num.ToString(); // kulturabhängig
string s2 = num.ToString("D6"); // führende Nullen
string hexStr = num.ToString("X"); // Hex
Performance / Span Parsing
ReadOnlySpan<char> span = "12345".AsSpan();
if (int.TryParse(span, out int fast)) { }
Checked Arithmetik Helpers (C# 11+)
int safe = int.CreateChecked((long)other);
int trunc = int.CreateTruncating(big);
int sat = int.CreateSaturating(big);
Pattern Matching / Ranges
bool ok = value is >= 0 and <= 10;
Flags Enum Beispiel
[Flags]
enum Perm { None=0, Read=1, Write=2, Exec=4 }
Perm p = Perm.Read | Perm.Write;
bool canWrite = p.HasFlag(Perm.Write); // langsamer
bool canWriteFast = (p & Perm.Write) != 0;
Häufige Fehlerquellen
- Ganzzahldivision statt Gleitkomma
- Overflow bei Multiplikation (checked nutzen)
- Parse ohne Fehlerprüfung
- Bitmasken falsch (Klammern, Vorzeichen)
Zusammenfassung Ganzzahlen
Kurzliste: + - * / % ++ -- Vergleiche, Bit: & | ^ ~ << >>, Parse/TryParse, ToString("D"/"X"), Math.* (Abs, Clamp, Min, Max, Sign), Random.Shared.Next, BitOperations (PopCount/Rotate/LeadingZeroCount), checked/unchecked, Flags-Enums.
Fließkommazahlen: Operationen und wichtige Methoden
Typen & Eigenschaften
- float (Single, 32 Bit IEEE 754, ca. 7 Dezimalstellen)
- double (64 Bit IEEE 754, ca. 15–17 Dezimalstellen) – Standard
- decimal (128 Bit, Basis-10, 28–29 signifikante Stellen, langsamer, für Geld/Buchhaltung)
float f = 1.5f;
double d = 1.5;
decimal m = 1.5m;
Basis-Operationen
double sum = a + b;
double diff = a - b;
double prod = a * b;
double quot = a / b;
double neg = -a;
Vergleich (Toleranz)
Direkter == Vergleich problematisch wegen Rundungsfehlern.
bool AreClose(double x, double y, double relEps = 1e-12, double absEps = 1e-15) {
double diff = Math.Abs(x - y);
if (diff <= absEps) return true;
return diff <= relEps * Math.Max(Math.Abs(x), Math.Abs(y));
}
Spezielle Werte
double nan = double.NaN;
double posInf = double.PositiveInfinity;
double negInf = double.NegativeInfinity;
bool isNan = double.IsNaN(nan);
bool isInf = double.IsInfinity(posInf);
bool isFinite = double.IsFinite(1.0);
double eps = double.Epsilon; // kleinste >0 Subnormal bei double
Decimal Besonderheiten
decimal preis = 12.34m;
decimal sum = preis * 3; // exakte Dezimalarithmetik (Basis 10)
Casting / Konvertierung
double dd = (double)f; // implizit float -> double
float ff = (float)dd; // explizit (Präzisionsverlust)
decimal dm = (decimal)dd; // kann Overflow werfen
double back = (double)dm;
Rundung
double r1 = Math.Round(2.345, 2); // Banker's (ToEven)
double r2 = Math.Round(2.345, 2, MidpointRounding.AwayFromZero);
double ceil = Math.Ceiling(x);
double floor = Math.Floor(x);
double trunc = Math.Truncate(x);
Math Funktionen
double abs = Math.Abs(x);
double pow = Math.Pow(2.0, 10);
double sq = Math.Sqrt(v);
double c = Math.Cos(a);
double s = Math.Sin(a);
double t = Math.Tan(a);
double exp = Math.Exp(a);
double ln = Math.Log(a);
double log10 = Math.Log10(a);
double clamped = Math.Clamp(x, 0.0, 1.0);
double min = Math.Min(a, b);
double max = Math.Max(a, b);
double copySign = Math.CopySign(magnitude:5.0, sign:-2.0);
MathF für float
float sf = MathF.Sqrt(3f);
Fused Multiply-Add (FMA)
double fma = Math.FusedMultiplyAdd(a, b, c); // a*b + c mit geringerer Rundung
Parsing & Formatierung
double v = double.Parse("1.23", CultureInfo.InvariantCulture);
if (double.TryParse("1.23", NumberStyles.Float, CultureInfo.InvariantCulture, out var parsed)) { }
string sG = v.ToString("G17", CultureInfo.InvariantCulture); // max Genauigkeit double
string sF = v.ToString("F2"); // 2 Nachkommastellen
string sE = v.ToString("E3"); // wissenschaftlich
string sR = v.ToString("R"); // Round-trip
Span Parsing (Performance)
ReadOnlySpan<char> span = "3.14159".AsSpan();
if (double.TryParse(span, NumberStyles.Float, CultureInfo.InvariantCulture, out double pi)) { }
Interop / Bit-Ebene
long bits = BitConverter.DoubleToInt64Bits(d);
double again = BitConverter.Int64BitsToDouble(bits);
int floatBits = BitConverter.SingleToInt32Bits(f);
NaN Verhalten
bool eqNaN = double.NaN == double.NaN; // false
bool notEq = double.NaN != double.NaN; // true
bool ordered = double.NaN < 1.0; // false
Aggregationen / Summe (Stabilität)
double StableSum(double[] data) {
double sum = 0, c = 0; // Kahan
foreach (var x in data) {
double y = x - c;
double t = sum + y;
c = (t - sum) - y;
sum = t;
}
return sum;
}
Random Gleitkomma
double r = Random.Shared.NextDouble(); // [0,1)
double rRange = Random.Shared.NextDouble() * (max - min) + min;
Performance Hinweise
- double schneller als decimal
- float spart Speicher (Arrays, GPU), aber geringere Präzision
- Avoid boxing bei Formatierung durch Span-basierte APIs (TryFormat)
Tolerante Sortierung Beispiel
Array.Sort(values, (x,y) => Math.Abs(x-y) < 1e-12 ? 0 : x.CompareTo(y));
Exceptions vermeiden
Verwendung von TryParse, keine Annahme auf exakte Darstellung (0.1 + 0.2 != 0.3 exakt).
Häufige Fehlerquellen
- Direkter == Vergleich ohne Toleranz
- decimal mit Math.* (gibt nur double-Überladungen für viele Funktionen)
- Kulturabhängige Dezimaltrennzeichen beim Parse
- Rundung (MidpointRounding falsch gewählt)
- Überlauf in decimal (Casting von sehr großen double)
Auswahlhilfe
- Wissenschaft / Grafik: float (wenn Speicher wichtig) oder double
- Standard: double
- Geld / Finanzen (exakte Dezimalstellen): decimal
Zusammenfassung Fließkomma
Kurzliste: + - * / Vergleich mit Toleranz, Math (Sqrt, Pow, Sin, Cos, Log, Exp, Clamp, Min/Max, CopySign, FusedMultiplyAdd), Round/Ceiling/Floor/Truncate, double.IsNaN/IsInfinity/IsFinite, Parse/TryParse, ToString("G17","F","E","R"), BitConverter.*Bits, Random.Shared.NextDouble, Kahan-Summe, decimal für Geld.
C# bool-Operationen und wichtige Methoden
Typ & Literale
bool t = true;
bool f = false;
Wird primär für Kontrollfluss genutzt; keine implizite Konvertierung zu/zur Zahl.
Logische Operatoren
bool not = !t; // Negation
bool both = a && b; // UND (short-circuit)
bool either = a || b; // ODER (short-circuit)
bool xor = a ^ b; // Exklusiv-Oder
& und | auf bool werten beide Operanden immer aus:
bool bothAll = a & b;
bool eitherAll = a | b;
Vergleich
bool eq = a == b;
bool ne = a != b;
Zuweisung vs Vergleich
// if (a = b) // Compilerfehler (gut gegen Verwechslung mit ==)
Operator-Präzedenz (Auszug)
! vor && vor ||. Klammern für Klarheit:
if (!(a || b) && c) { }
De Morgan
!(a && b) == !a || !b;
!(a || b) == !a && !b;
Ternärer Operator
string msg = ok ? "OK" : "FAIL";
Nullable bool (bool?)
Drei Zustände: true, false, null.
bool? x = null;
if (x is true) { }
bool res = x ?? false;
bool onlyTrue = x == true;
Pattern Matching
if (flag is true) { }
switch (flag) {
case true: break;
case false: break;
}
Parsing & Formatierung
bool b1 = bool.Parse("true");
if (bool.TryParse("False", out var b2)) { }
string s = b2.ToString(); // "True"/"False"
Konvertierung zu Zahl
int bit = flag ? 1 : 0;
Seiteneffekte erzwingen
if (CheckA() & CheckB()) { } // beide werden sicher ausgeführt
if (CheckA() && CheckB()) { } // CheckB nur bei wahr von CheckA
Guard / Früher Rückgabepunkt
if (!isValid) return;
Debug / Verträge
Debug.Assert(condition);
Trace.Assert(condition);
Häufige Fehlerquellen
- Erwartete Ausführung des rechten Operanden bei && / || (short-circuit)
- Nutzung von & / | statt && / || (unbeabsichtigte Seiteneffekte)
- Null nicht beachtet bei bool?
- String-Parsing mit falscher Groß/Kleinschreibung (TryParse berücksichtigt beides)
Kurzliste
true/false, !, &&, ||, ^, &, | (kein short-circuit), ?:, ==, !=, bool.Parse/TryParse, bool?, Pattern (is true/false), De Morgan, Debug.Assert.