.First vs .FirstOrDefault in C#: Wann was verwenden?

Online Python-Trainer für Anfänger

Lernen Sie Python einfach ohne theoretische Überlastung. Lösen Sie praktische Aufgaben mit automatischer Überprüfung und schreiben Sie Code direkt im Browser.

Kurs starten

Einleitung: Die bekannte Angst jedes C#-Entwicklers

\n

Stell dir vor: Du schreibst eine Abfrage für eine Datenbank oder eine In-Memory-Collection. Du brauchst das erste Element, das eine Bedingung erfüllt. Du bist sicher, dass dieses Element garantiert existiert. Oder doch nicht? Genau hier beginnt die Qual der Wahl: .First() oder .FirstOrDefault()?

\n

Diese Frage ist ein absoluter Dauerbrenner auf Stack Overflow mit tausenden Aufrufen. Und das zu Recht. Die Wahl zwischen diesen beiden Methoden kann den Unterschied zwischen sauberem, vorhersagbarem Code und einem plötzlichen InvalidOperationException in der Produktion bedeuten. Lass uns ein für alle Mal klären, wann welche Methode verwendet wird, und die Zweifel für immer vergessen.

\n\n

Das Wichtigste in Kürze: Wo liegt der Unterschied?

\n

Beide Methoden tun fast dasselbe: Sie geben das erste Element einer Sequenz zurück, das eine Bedingung erfüllt (oder einfach das erste Element, wenn keine Bedingung angegeben ist). Es gibt jedoch einen entscheidenden Unterschied:

\n
    \n
  • .First() – Wenn kein Element gefunden wird, wird eine System.InvalidOperationException ausgelöst.
  • \n
  • .FirstOrDefault() – Wenn kein Element gefunden wird, wird der Standardwert des Typs zurückgegeben (null für Referenztypen, 0 für int, false für bool usw.).
  • \n
\n

Klingt einfach. Aber der Teufel steckt, wie immer, im Detail.

\n\n

Wann .First() verwenden: Wenn es "sein muss, Punkt"

\n

Verwende .First(), wenn deine Geschäftslogik streng garantiert, dass das Element existiert. Wenn es nicht da ist, handelt es sich um eine Ausnahmesituation, einen Fehler in den Daten oder der Anwendungslogik.

\n\n

Beispiel 1: Suche nach einer eindeutigen ID

\n

Wenn du einen Benutzer anhand seines Primary Keys in der Datenbank suchst (z. B. nach Id) und sicher bist, dass dieser Benutzer existiert, verwende .First():

\n
public class UserService\n{\n    private readonly AppDbContext _context;\n\n    public UserService(AppDbContext context)\n    {\n        _context = context;\n    }\n\n    public User GetUserById(int userId)\n    {\n        // Wir erwarten, dass ein Benutzer mit dieser ID existiert.\n        // Wenn nicht – das ist ein ernstes Problem, besser eine Exception werfen.\n        return _context.Users.First(u => u.Id == userId);\n    }\n}
\n

Die Exception ist in diesem Fall ein Alarmzeichen. Sie sagt: "Hey, die Daten sind beschädigt, oder jemand hat eine falsche ID übergeben". Du fängst diese Exception weiter oben im Stack und behandelst sie als kritischen Fehler.

\n\n

Beispiel 2: Erstes Element nach einer Sortierung (garantiert)

\n

Wenn du eine Liste sortierst und das erste Element nimmst, und die Liste definitiv Elemente enthält:

\n
var highestScore = players\n    .OrderByDescending(p => p.Score)\n    .First(); // Es kann keine 0 Spieler geben, das haben wir vorher geprüft
\n

Wenn du vorher geprüft hast, dass die Collection nicht leer ist (z. B. if (players.Any())), dann ist .First() deine Wahl.

\n\n

Wann .FirstOrDefault() verwenden: Wenn das Element fehlen darf

\n

Die goldene Regel: Wenn das Fehlen eines Ergebnisses ein normaler Zustand und kein Fehler ist, verwende .FirstOrDefault().

\n\n

Beispiel 1: Optionale Suche

\n

Stell dir vor, wir suchen eine Bestellung anhand der Nummer, aber die Bestellung könnte noch nicht angelegt sein:

\n
public Order FindOrderByNumber(string orderNumber)\n{\n    // Die Bestellung könnte nicht existieren. Das ist normal.\n    return _context.Orders\n        .FirstOrDefault(o => o.OrderNumber == orderNumber);\n    // Gibt null zurück, wenn die Bestellung nicht gefunden wird.\n}
\n

Nach dem Aufruf dieser Methode müssen wir das Ergebnis auf null prüfen:

\n
var order = FindOrderByNumber("ORD-12345");\nif (order != null)\n{\n    // Arbeiten mit der Bestellung\n    Console.WriteLine($"Bestellung gefunden: {order.Id}");\n}\nelse\n{\n    Console.WriteLine("Bestellung nicht gefunden. Lege neue an.");                

Blogs

Buchempfehlungen