【问题标题】:Meaning of the syntax: return _(); IEnumerable<TSource> _() [duplicate]语法含义:return _(); IEnumerable<TSource> _() [重复]
【发布时间】:2017-08-28 02:34:20
【问题描述】:

在下面的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;
        }
    }
}

【问题讨论】:

    标签: c# syntax


    【解决方案1】:

    return 语句之后插入换行符可能更容易理解代码:

    return _();
    
    IEnumerable<TSource> _()
    {
        var knownKeys = new HashSet<TKey>(comparer);
        foreach (var element in source)
        {
            if (knownKeys.Add(keySelector(element)))
                yield return element;
        }
    }
    

    在这种情况下,下划线只是 local function 的任意名称(这是 C# 7.0 中引入的新功能)。如果您愿意,可以将下划线替换为更具描述性的名称:

    return DistinctByHelper();
    
    IEnumerable<TSource> DistinctByHelper()
    {
        var knownKeys = new HashSet<TKey>(comparer);
        foreach (var element in source)
        {
            if (knownKeys.Add(keySelector(element)))
                yield return element;
        }
    }
    

    作为局部函数,_(或DistinctByHelper)方法可以访问DistinctBy方法的所有变量。

    顺便说一下,这里有两个方法的原因是,如果任何参数为空,ArgumentNullException 将在调用DistinctBy 时立即抛出,而不是在枚举结果时(由于存在yield return 声明)。

    【讨论】:

    • 真的希望这种模式不会流行。太丑了。
    • 我从不喜欢本地函数缺少任何类型的标识关键字——例如,它们很容易与本地委托或对象初始化器列表混淆。一个简单的 func 关键字或强制 lambda 语法 =&gt; 会有所帮助)。
    • 无论如何这里似乎不需要本地函数。
    • docs 给出了两个例子来说明为什么可以使用这样的本地函数。主要是在创建而不是迭代/等待时抛出异常。
    • 同意。下划线名称 + 在同一行开始定义并不适合我。
    猜你喜欢
    • 2012-08-14
    • 1970-01-01
    • 2012-02-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多