.First 与 .FirstOrDefault 在 C# 中:何时选择哪一个?

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

引言:每位 C# 开发者都熟悉的恐惧

\n

设想一个场景:您正在对数据库或内存中的集合编写查询。您需要获取满足条件的第一个元素。您确信该元素一定存在。或者您并不确定?于是,纠结就开始了:是用 .First() 还是 .FirstOrDefault()?

\n

这个问题在 Stack Overflow 上可是个热门话题,浏览量成千上万。这并非没有道理。在这两个方法之间做出选择,可能意味着代码是干净、可预测的,还是在生产环境中突然抛出 InvalidOperationException。让我们一劳永逸地弄清楚何时使用哪个方法,从此不再犹豫。

\n\n

核心要点:区别是什么?

\n

这两个方法做的事情几乎相同:返回序列中满足条件的第一个元素(如果未指定条件,则返回第一个元素)。但有一个关键区别:

\n
    \n
  • .First() — 如果未找到元素,则抛出 System.InvalidOperationException 异常。
  • \n
  • .FirstOrDefault() — 如果未找到元素,则返回该类型的默认值(引用类型返回 null,int 返回 0,bool 返回 false 等)。
  • \n
\n

看起来很简单。但魔鬼,一如既往,藏在细节中。

\n\n

何时使用 .First():当“必须存在,没得商量”

\n

当您的业务逻辑严格保证元素存在时,请使用 .First()。如果不存在,那就是异常情况,是数据或应用逻辑中的错误。

\n\n

示例 1:按唯一标识符查找

\n

如果您按数据库中的主键(例如 Id)查找用户,并且确信该用户存在,请使用 .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        // 我们期望具有此 ID 的用户存在。\n        // 如果不存在——这是一个严重问题,最好让它抛出异常。\n        return _context.Users.First(u => u.Id == userId);\n    }\n}
\n

在这种情况下,异常就是一个警报。它说:“嘿,数据已损坏,或者有人传入了错误的 ID”。您会在调用栈的更高层捕获这个异常,并将其作为严重错误处理。

\n\n

示例 2:排序后的第一个元素(保证存在)

\n

如果您对列表进行排序并取第一个元素,并且列表中肯定有元素:

\n
var highestScore = players\n    .OrderByDescending(p => p.Score)\n    .First(); // 玩家数量不可能为 0,我们之前已经检查过了
\n

如果您事先检查过集合不为空(例如 if (players.Any())),那么 .First() 就是您的选择。

\n\n

何时使用 .FirstOrDefault():当元素可能不存在时

\n

黄金法则:如果缺少结果是正常情况,而不是错误,请使用 .FirstOrDefault()。

\n\n

示例 1:可选查找

\n

假设我们按订单号查找订单,但订单可能尚未创建:

\n
public Order FindOrderByNumber(string orderNumber)\n{\n    // 订单可能不存在。这是正常的。\n    return _context.Orders\n        .FirstOrDefault(o => o.OrderNumber == orderNumber);\n    // 如果未找到订单,则返回 null。\n}
\n

调用此方法后,我们必须检查结果是否为 null:

\n
var order = FindOrderByNumber("ORD-12345");\nif (order != null)\n{\n    // 处理订单\n    Console.WriteLine($"订单已找到:{order.Id}");\n}\nelse\n{\n    Console.WriteLine("未找到订单。正在创建新订单。");                

博客

书籍推荐