在C#的LINQ操作中,First和FirstOrDefault都是用于从集合中返回第一个匹配元素的方法,但两者的行为逻辑存在明显差异,适用场景也各不相同。下面先介绍两者的基础用法,再对比区别和使用场景。

First方法的基础用法
First方法的作用是返回集合中满足指定条件的第一个元素,如果没有找到匹配的元素,会直接抛出InvalidOperationException异常。它有两种常用的重载形式,一种是不带条件的直接获取第一个元素,另一种是传入条件表达式筛选后获取第一个元素。
以下是First方法的使用示例:
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static void Main()
{
List<int> numbers = new List<int> { 1, 3, 5, 7, 9 };
// 不带条件,获取集合第一个元素
int firstNum = numbers.First();
Console.WriteLine($"集合第一个元素:{firstNum}"); // 输出 1
// 带条件,获取第一个大于5的元素
int firstGreaterThan5 = numbers.First(n => n > 5);
Console.WriteLine($"第一个大于5的元素:{firstGreaterThan5}"); // 输出 7
// 没有匹配元素时调用First会抛异常
try
{
int notExist = numbers.First(n => n > 10);
}
catch (InvalidOperationException ex)
{
Console.WriteLine($"异常信息:{ex.Message}"); // 输出 序列不包含任何匹配元素
}
}
}
FirstOrDefault方法的基础用法
FirstOrDefault方法的作用是返回集合中满足指定条件的第一个元素,如果没有找到匹配的元素,会返回该集合元素类型的默认值,不会抛出异常。它的重载形式和First一致,同样支持无条件和带条件的两种使用方式。
以下是FirstOrDefault方法的使用示例:
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static void Main()
{
List<int> numbers = new List<int> { 1, 3, 5, 7, 9 };
List<string> names = new List<string> { "张三", "李四", "王五" };
// 不带条件,获取集合第一个元素
int firstNum = numbers.FirstOrDefault();
Console.WriteLine($"集合第一个元素:{firstNum}"); // 输出 1
// 带条件,获取第一个大于5的元素
int firstGreaterThan5 = numbers.FirstOrDefault(n => n > 5);
Console.WriteLine($"第一个大于5的元素:{firstGreaterThan5}"); // 输出 7
// 没有匹配元素时,返回元素类型的默认值
int notExistNum = numbers.FirstOrDefault(n => n > 10);
Console.WriteLine($"不存在匹配元素时的返回值:{notExistNum}"); // 输出 0,int类型默认值为0
string notExistName = names.FirstOrDefault(n => n == "赵六");
Console.WriteLine($"不存在匹配字符串时的返回值:{notExistName ?? "null"}"); // 输出 null,string类型默认值为null
}
}
First和FirstOrDefault的核心区别
两者的核心差异主要体现在无匹配元素时的处理逻辑上,具体对比如下:
| 对比维度 | First | FirstOrDefault |
|---|---|---|
| 无匹配元素时的行为 | 抛出InvalidOperationException异常 | 返回元素类型的默认值 |
| 适用前提 | 确定集合中一定存在匹配元素 | 不确定集合中是否存在匹配元素 |
| 返回值处理 | 不需要额外处理默认值 | 需要判断返回值是否为默认值,避免后续逻辑出错 |
什么时候用First?什么时候用FirstOrDefault?
适合使用First的场景
当你能够确定集合中一定存在满足条件的元素,或者如果不存在匹配元素就属于程序异常逻辑时,优先使用First。比如从数据库查询主键对应的记录,主键是唯一的,正常情况下一定存在对应的数据,如果不存在就说明数据有问题,抛出异常的反馈更明确。
示例场景:根据唯一用户ID查询用户信息,ID对应的用户一定存在:
using System;
using System.Collections.Generic;
using System.Linq;
class User
{
public int Id { get; set; }
public string Name { get; set; }
}
class Program
{
static void Main()
{
List<User> users = new List<User>
{
new User { Id = 1, Name = "张三" },
new User { Id = 2, Name = "李四" }
};
// 确定ID为1的用户存在,使用First
User targetUser = users.First(u => u.Id == 1);
Console.WriteLine($"查询到的用户:{targetUser.Name}"); // 输出 张三
}
}
适合使用FirstOrDefault的场景
当你不确定集合中是否存在满足条件的元素,且不存在匹配元素属于正常业务逻辑时,优先使用FirstOrDefault。比如搜索功能,用户输入关键词后可能没有匹配的结果,这时候返回默认值,后续判断默认值处理空结果即可,不需要抛出异常。
示例场景:搜索用户名包含指定关键词的用户,可能没有匹配结果:
using System;
using System.Collections.Generic;
using System.Linq;
class User
{
public int Id { get; set; }
public string Name { get; set; }
}
class Program
{
static void Main()
{
List<User> users = new List<User>
{
new User { Id = 1, Name = "张三" },
new User { Id = 2, Name = "李四" }
};
// 不确定是否存在名字包含"王"的用户,使用FirstOrDefault
User searchResult = users.FirstOrDefault(u => u.Name.Contains("王"));
if (searchResult == null)
{
Console.WriteLine("未查询到匹配的用户");
}
else
{
Console.WriteLine($"查询到的用户:{searchResult.Name}");
}
}
}
注意事项
- 使用FirstOrDefault之后,一定要判断返回值是否为默认值,尤其是引用类型,避免后续操作出现空引用异常。
- 如果集合本身为null,无论是调用First还是FirstOrDefault,都会抛出ArgumentNullException异常,使用前可以先判断集合是否为空。
- 如果只需要判断集合中是否存在匹配元素,不需要获取元素本身,优先使用Any方法,性能比First和FirstOrDefault更好。
C#LINQFirstFirstOrDefaultFirstOrDefault_区别修改时间:2026-07-03 22:00:34