You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C# Linq如何实现带自定义默认值的FirstOr方法?

实现自定义默认值的FirstOr方法

要实现支持自定义默认值的FirstOr方法,最直接的方式是给IEnumerable<T>编写扩展方法,和Linq原生方法的风格对齐。我们需要实现两个重载:一个不带筛选条件,直接返回序列第一个元素或自定义默认值;另一个带筛选条件,返回第一个符合条件的元素或自定义默认值。

1. 无筛选条件的FirstOr

先处理最基础的场景:如果序列有元素,返回第一个;如果为空,返回传入的自定义默认值。

public static class EnumerableExtensions
{
    public static T FirstOr<T>(this IEnumerable<T> source, T defaultValue)
    {
        // 校验参数合法性,避免空引用
        if (source == null)
            throw new ArgumentNullException(nameof(source));
        
        foreach (var item in source)
        {
            // 找到第一个元素直接返回,无需遍历整个序列
            return item;
        }
        
        // 序列为空时返回自定义默认值
        return defaultValue;
    }
}

这里直接用foreach遍历,找到第一个元素就返回,比先调用Any()再调用First()更高效(避免两次遍历序列),同时也不会出现“序列中第一个元素刚好是类型默认值时误返回自定义值”的问题。

2. 带筛选条件的FirstOr

再实现带筛选逻辑的重载,和原生First(predicate)对应:

public static class EnumerableExtensions
{
    // 上面的无参重载也放在这个类里
    public static T FirstOr<T>(this IEnumerable<T> source, Func<T, bool> predicate, T defaultValue)
    {
        // 校验参数
        if (source == null)
            throw new ArgumentNullException(nameof(source));
        if (predicate == null)
            throw new ArgumentNullException(nameof(predicate));
        
        foreach (var item in source)
        {
            if (predicate(item))
            {
                return item;
            }
        }
        
        // 没有符合条件的元素时返回自定义默认值
        return defaultValue;
    }
}

使用示例

写完扩展方法后,就可以像用Linq原生方法一样调用:

// 示例1:空序列返回自定义默认值
var emptyList = new List<int>();
var result1 = emptyList.FirstOr(-1); // 结果为-1

// 示例2:非空序列返回第一个元素
var numbers = new List<int> { 1, 2, 3 };
var result2 = numbers.FirstOr(-1); // 结果为1

// 示例3:带筛选条件,没找到符合条件的元素返回自定义值
var strings = new List<string> { "apple", "banana" };
var result3 = strings.FirstOr(s => s.StartsWith("c"), "Not Found"); // 结果为"Not Found"

为什么不用FirstOrDefault+判断?

有人可能会想,直接用source.FirstOrDefault() ?? defaultValue?但这种写法有问题:如果序列中第一个元素刚好是值类型的默认值(比如int的0),或者引用类型的null,就会错误地返回自定义默认值,而不是序列本身的元素。所以直接遍历的方式更可靠。

内容的提问来源于stack exchange,提问作者pete

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 20:22:09