我知道这听起来可能很奇怪,但我甚至不知道如何在互联网上搜索这种语法,而且我也不知道确切的意思.

所以我看了一些MoreLINQ代码,然后我注意到了这个方法

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 _();

推荐答案

这是支持本地功能的C#7.0....

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));

        // This is basically executing _LocalFunction()
        return _LocalFunction(); 

        // This is a new inline method, 
        // return within this is only within scope of
        // this method
        IEnumerable<TSource> _LocalFunction()
        {
            var knownKeys = new HashSet<TKey>(comparer);
            foreach (var element in source)
            {
                if (knownKeys.Add(keySelector(element)))
                    yield return element;
            }
        }
    }

当前版本为Func<T>的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));

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

        // This is basically executing func
        return func(); 

    }

诀窍是,()在使用后被声明,这是非常好的.

Pratical use of local functions

上面的示例只是演示如何使用内联方法,但如果只调用一次该方法,则很可能没有任何用处.

但在上面的例子中,正如PhoshiLuaan的 comments 中所提到的,使用局部函数有一个优点.由于除非有人对函数进行迭代,否则不会执行具有yield return的函数,因此在这种情况下,将执行本地函数之外的方法,并执行参数验证,即使没有人对该值进行迭代.

我们在方法中多次重复代码,让我们看一下这个示例.

  public void ValidateCustomer(Customer customer){

      if( string.IsNullOrEmpty( customer.FirstName )){
           string error = "Firstname cannot be empty";
           customer.ValidationErrors.Add(error);
           ErrorLogger.Log(error);
           throw new ValidationError(error);
      }

      if( string.IsNullOrEmpty( customer.LastName )){
           string error = "Lastname cannot be empty";
           customer.ValidationErrors.Add(error);
           ErrorLogger.Log(error);
           throw new ValidationError(error);
      }

      ... on  and on... 
  }

我可以用...

  public void ValidateCustomer(Customer customer){

      void _validate(string value, string error){
           if(!string.IsNullOrWhitespace(value)){

              // i can easily reference customer here
              customer.ValidationErrors.Add(error);

              ErrorLogger.Log(error);
              throw new ValidationError(error);                   
           }
      }

      _validate(customer.FirstName, "Firstname cannot be empty");
      _validate(customer.LastName, "Lastname cannot be empty");
      ... on  and on... 
  }

.net相关问答推荐

找不到包Microsoft.VisualStudio.Azure.Containers.Tools.Targets

在`MAUI`应用中使用Android`MediaPlayer`的`prepare`方法只在发布模式下和在物理设备上崩溃

在数据网格中:如何在更改单元格 A 中的值后显示单元格 B 中的更改

在 Rx 中,处理线程安全是否是消费者(IObserver)的责任?

查找 2 个已知值之间的字符串

在 C# 中将字符串转换为 colored颜色

maxRequestLength 的最大值?

您是否使用 TestInitialize 或测试类构造函数来准备每个测试?为什么?

使用 Windows 服务和 C# 检测 USB 驱动器插入和移除

有没有办法以编程方式最小化窗口

如何右对齐 DataGridView 列中的文本?

属性应该与其类型同名吗?

C# 的 Actors 有什么好的实现吗?

C#:获得完整的桌面大小?

软件包版本始终为 1.0.0,带有 dotnet pack

资源(.resx)文件有什么好处?

string.Empty vs null.你用哪一个?

Environment.GetFolderPath(...CommonApplicationData) 在 Vista 上仍然返回C:\Documents and Settings\

如何比较泛型类型的值?

什么时候使用 Tuple 和 KeyValuePair 比较好?