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

如何在C#中实现不抛出异常的MinBy方法?

实现安全的过滤后MinBy函数

针对你需要的“先过滤、再按映射值取最小值,空序列返回null”的需求,这里提供两种无需捕获异常、简洁优雅的实现方式,同时支持引用类型和值类型:

方案1:预过滤+非空判断(简洁直观)

先过滤序列并缓存结果(避免两次枚举),再判断是否存在有效元素,不存在则返回null,存在则调用MinBy:

using System.Linq;

public static T? MinByFiltered<T, TKey>(IEnumerable<T> source, Func<T, bool> filter, Func<T, TKey> keySelector) 
    where TKey : IComparable<TKey>
{
    var filteredItems = source.Where(filter).ToList();
    return filteredItems.Any() ? filteredItems.MinBy(keySelector) : default;
}
  • 优点:代码简洁易懂,利用LINQ原生方法实现,可读性高
  • 注意:ToList()会将过滤后的元素加载到内存,适合中小规模序列;如果是超大序列,推荐用方案2

方案2:单次枚举的Aggregate实现(高效低内存)

通过Aggregate逐个遍历过滤后的元素,手动维护当前最小值,全程仅枚举一次序列,无额外内存开销:

using System.Linq;

public static T? MinByFiltered<T, TKey>(IEnumerable<T> source, Func<T, bool> filter, Func<T, TKey> keySelector) 
    where TKey : IComparable<TKey>
{
    var aggregateResult = source.Where(filter)
        .Aggregate(
            (CurrentMin: default(T), HasValidElements: false),
            (accumulator, currentItem) => 
            {
                if (!accumulator.HasValidElements)
                {
                    return (currentItem, true);
                }
                
                var currentKey = keySelector(currentItem);
                var minKey = keySelector(accumulator.CurrentMin!);
                return currentKey.CompareTo(minKey) < 0 
                    ? (currentItem, true) 
                    : accumulator;
            });

    return aggregateResult.HasValidElements ? aggregateResult.CurrentMin : default;
}
  • 优点:仅遍历一次序列,内存占用低,适合处理大数据量或流式数据
  • 逻辑说明:用元组记录当前最小值和是否存在有效元素,遍历过程中不断更新最小值,最后根据标记返回结果

两种实现都不会触发MinBy的InvalidOperationException,因为只有在存在有效元素时才会执行最小值判断;返回值T?在引用类型时自动返回null,值类型时返回可空值类型的null(比如int?),完全符合你的需求。

内容的提问来源于stack exchange,提问作者user-id-14900042

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 19:50:11