2017-08-28 18 views
7

Trong mã C# dưới đây, tôi thấy việc sử dụng _() lạ. Bất cứ ai có thể giải thích điều này có nghĩa là gì?Ý nghĩa cú pháp: 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)); 

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

Trả lời

9

Mã này có thể dễ hiểu hơn bằng cách chèn một ngắt dòng sau return tuyên bố:

return _(); 

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

Trong bối cảnh này, các dấu gạch dưới chỉ là một cái tên tùy ý cho một local function (mà là một mới tính năng được giới thiệu trong C# 7.0). Nếu bạn thích, bạn có thể thay thế gạch dưới bởi một tên mô tả hơn:

return DistinctByHelper(); 

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

Là một chức năng địa phương, phương pháp _ (hoặc DistinctByHelper) có thể truy cập vào tất cả các biến của phương pháp DistinctBy.

Bằng cách này, lý do có hai phương pháp ở đây là do đó, trong trường hợp bất kỳ đối số là null, ArgumentNullException sẽ được ném ngay lập tức khi DistinctBy được gọi thay vì khi kết quả được liệt kê (do sự hiện diện của yield return tuyên bố).

+4

Tôi * thực sự * hy vọng mẫu này không bắt kịp. Đó chỉ là xấu xí. –

+0

Tôi không bao giờ thích cách các hàm cục bộ thiếu bất kỳ loại từ khóa xác định nào - chúng dễ dàng bị nhầm lẫn với danh sách đại biểu hoặc đối tượng khởi tạo đối tượng cục bộ, chẳng hạn. Từ khóa 'func' đơn giản hoặc cú pháp lambda bắt buộc' => 'sẽ giúp ích). – Dai

+0

Chức năng cục bộ có vẻ không cần thiết ở đây. –

Các vấn đề liên quan