为什么最好使用局部函数而不是仅仅内联代码?

c#

我在这里找到了这个代码:

public static IEnumerable<TSource> DistinctBy<TSource, TKey>(this IEnumerable<TSource> source,
        Func<TSource, TKey> keySelector, IEqualityComparer<TKey>? comparer)
{
    if (source == null) throw new ArgumentNullException(nameof(source));
    if (keySelector == null) throw new ArgumentNullException(nameof(keySelector));
    return _(); IEnumerable<TSource> _()
    {
        var knownKeys = new HashSet<TKey>(comparer);
        foreach (var element in source)
        {
            if (knownKeys.Add(keySelector(element)))
                yield return element;
        }
    }
}

起初我不明白这部分return _(); IEnumerable<TSource> _(),但我意识到这是一个在同一行中调用和声明的本地函数。这是在这里完成的。

我的问题是:与简单地内联该代码相比有什么优势吗?

public static IEnumerable<TSource> DistinctBy<TSource, TKey>(this IEnumerable<TSource> source,
        Func<TSource, TKey> keySelector, IEqualityComparer<TKey>? comparer)
{
    if (source == null) throw new ArgumentNullException(nameof(source));
    if (keySelector == null) throw new ArgumentNullException(nameof(keySelector));
    var knownKeys = new HashSet<TKey>(comparer);
    foreach (var element in source)
    {
        if (knownKeys.Add(keySelector(element)))
            yield return element;
    }
}

我会说当前版本更冗长并且缩进更多,那么优点是什么?只是口味问题吗?

回答

如果或为空,带有本地方法的版本将立即抛出,因为它没有用迭代器块实现。sourcekeySelector

“内联”版本使用迭代器块,因此在调用代码开始迭代返回的IEnumerable<TSource>.

一般来说,预先验证可以更容易地发现和理解错误:堆栈跟踪更清晰,在“进行中断的调用”和“看到失败”之间没有延迟。

同样的方法也可用于编写急切失败的任务返回方法:编写一个“常规”任务返回方法,在执行验证后调用异步本地方法。


以上是为什么最好使用局部函数而不是仅仅内联代码?的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>