.First vs .FirstOrDefault in C#: When to Choose What?

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Introduction: The Familiar Fear of Every C# Developer

\n

Imagine this: you are writing a query to a database or an in-memory collection. You need to get the first element that satisfies a condition. You are sure that such an element definitely exists. Or are you not sure? This is where the dance begins: .First() or .FirstOrDefault()?

\n

This question is a real hit on Stack Overflow with thousands of views. And for good reason. The choice between these two methods can mean the difference between clean, predictable code and a sudden InvalidOperationException in Production. Let's finally figure out once and for all which method to use when, and forget about doubts forever.

\n\n

The Main Point in Short: What's the Difference?

\n

Both methods do almost the same thing: they return the first element of a sequence that satisfies a condition (or just the first element if no condition is specified). But there is a critical difference:

\n
    \n
  • .First() — if the element is not found, it throws a System.InvalidOperationException.
  • \n
  • .FirstOrDefault() — if the element is not found, it returns the default value for the type (null for reference types, 0 for int, false for bool, etc.).
  • \n
\n

It seems simple. But the devil, as always, is in the details.

\n\n

When to Use .First(): When "It Must Exist, Period"

\n

Use .First() when your business logic strictly guarantees that the element exists. If it doesn't — that's an exceptional situation, an error in the data or application logic.

\n\n

Example 1: Searching by a Unique Identifier

\n

If you are looking for a user by their Primary Key in the database (e.g., by Id), and you are sure that such a user exists, use .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        // We expect a user with this ID to exist.\n        // If not — this is a serious problem, better let the exception be thrown.\n        return _context.Users.First(u => u.Id == userId);\n    }\n}
\n

An exception in this case is an alarm signal. It says: "Hey, the data is corrupted, or someone passed an invalid ID." You will catch this exception higher up the stack and handle it as a critical error.

\n\n

Example 2: First Element After Sorting (Guaranteed)

\n

If you sort a list and take the first element, and the list definitely has elements:

\n
var highestScore = players\n    .OrderByDescending(p => p.Score)\n    .First(); // There cannot be 0 players; we checked this earlier
\n

If you have previously verified that the collection is not empty (e.g., if (players.Any())), then .First() is your choice.

\n\n

When to Use .FirstOrDefault(): When the Element Might Not Exist

\n

The golden rule: If the absence of a result is a normal situation, not an error, use .FirstOrDefault().

\n\n

Example 1: Optional Search

\n

Imagine we are looking for an order by its number, but the order might not have been created yet:

\n
public Order FindOrderByNumber(string orderNumber)\n{\n    // The order might not exist. That's normal.\n    return _context.Orders\n        .FirstOrDefault(o => o.OrderNumber == orderNumber);\n    // Returns null if the order is not found.\n}
\n

After calling this method, we must check the result for null:

\n
var order = FindOrderByNumber("ORD-12345");\nif (order != null)\n{\n    // Work with the order\n    Console.WriteLine($"Order found: {order.Id}");\n}\nelse\n{\n    Console.WriteLine("Order not found. Creating a new one.");                

Blogs

Book Recommendations