奇数返回语法语句

我知道这可能听起来很奇怪,但我不知道如何在互联网上search这个语法,也不知道究竟是什么意思。

所以我看了一些更多的LINQ代码,然后我注意到了这个方法

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,它支持本地function….

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

目前C#与Func<T>

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

诀窍是,_()在使用之后被声明,这非常好。

实用的地方function

上面的例子只是一个演示如何使用内联方法,但是如果你打算只调用一次方法,那么很可能是没用的。

但是在上面的例子中,如PhoshiLuaan的评论所提到的那样 ,使用本地function是有优势的。 因为带有yield return的函数不会被执行,除非有人迭代它,在这种情况下,将执行局部函数外部的方法,并且即使没有人重复该值也将执行参数validation。

我们多次在方法中重复了代码,让我们看这个例子。

  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... } 

考虑更简单的例子

 void Main() { Console.WriteLine(Foo()); // Prints 5 } public static int Foo() { return _(); // declare the body of _() int _() { return 5; } } 

_()是在包含return语句的方法中声明的本地函数。