Kurse:Datentypen-C-Sharp

Aus ahrensburg.city
Zur Navigation springen Zur Suche springen

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.