为什么使用局部函数比内联代码更好?
Why is better to use a local function instead of just inlining the code?
我在 here 中找到了这段代码:
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> _()
,后来才知道是在同一行调用和声明的局部函数。已完成 here.
我的问题是:与简单地内联该代码相比有什么优势吗?
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;
}
}
我想说现在的版本更冗长,缩进更多,那么有什么好处呢?只是品味问题?
如果 source
或 keySelector
为 null,具有本地方法的版本将立即抛出 ,因为它没有使用迭代器块实现。
“内联”版本使用迭代器块,因此 none 代码(包括验证)将一直执行,直到调用代码开始迭代返回的 IEnumerable<TSource>
。
一般来说,急切的验证更容易发现和理解错误:堆栈跟踪更清晰,并且在“进行失败的调用”和“看到失败”之间没有延迟。
同样的方法也可用于编写急切失败的任务返回方法:编写一个“常规”任务返回方法,在执行验证后调用异步本地方法。
我在 here 中找到了这段代码:
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> _()
,后来才知道是在同一行调用和声明的局部函数。已完成 here.
我的问题是:与简单地内联该代码相比有什么优势吗?
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;
}
}
我想说现在的版本更冗长,缩进更多,那么有什么好处呢?只是品味问题?
如果 source
或 keySelector
为 null,具有本地方法的版本将立即抛出 ,因为它没有使用迭代器块实现。
“内联”版本使用迭代器块,因此 none 代码(包括验证)将一直执行,直到调用代码开始迭代返回的 IEnumerable<TSource>
。
一般来说,急切的验证更容易发现和理解错误:堆栈跟踪更清晰,并且在“进行失败的调用”和“看到失败”之间没有延迟。
同样的方法也可用于编写急切失败的任务返回方法:编写一个“常规”任务返回方法,在执行验证后调用异步本地方法。