Linq調試實時輸出信息擴展方法(摘抄)

  • 2019 年 10 月 10 日
  • 筆記

原文在此

[譯]如何在C#中調試LINQ查詢

原linq語句:

var res = employees  .Where(e => e.Gender == "Male")  .Take(3)  .Where(e => e.Salary > avgSalary)  .OrderBy(e => e.Age);

擴展方法:

        public static IEnumerable<T> LogLINQ<T>(this IEnumerable<T> enumerable, string logName, Func<T, string> printMethod)          {  #if DEBUG              int count = 0;              foreach (var item in enumerable)              {                  if (printMethod != null)                  {                      Debug.WriteLine($"{logName}|item {count} = {printMethod(item)}");                  }                  count++;                  yield return item;              }              Debug.WriteLine($"{logName}|count = {count}");  #else               return enumerable;  #endif          }

使用方法

var res = employees      .LogLINQ("source", e => e.Name)      .Where(e => e.Gender == "Male")      .LogLINQ("logWhere", e => e.Name)      .Take(3)      .LogLINQ("logTake", e => e.Name)      .Where(e => e.Salary > avgSalary)      .LogLINQ("logWhere2", e => e.Name)      .OrderBy(e => e.Age);

說明和解釋:

  • 在LINQ查詢中的每個操作之後放置 LogLINQ方法。它可以選擇打印通過此操作的所有項目和總數。
  • logName是每個輸出的前綴,可以輕鬆查看編寫它的查詢步驟。我喜歡將其命名為之後操作相同的名稱。
  • Fun<T,string>printMethod允許打印給定項目的任何內容。在上面的示例中,我選擇使用 e=>e.Name打印員工的姓名,當為 null時,除總數外,不會打印任何內容。
  • 為了優化,此方法盡在調試模式下有效( #if DEBUG)。在發佈模式下,它什麼都不做。
  • 每個項目都按順序打印,無需等待操作結束,這是因為LINQ的 lazy 特性。以下是查看單個操作結果的提示:將整個輸出複製到 notepad++。然後使用Ctrl+Shift+F(Find)並查找日誌前綴(例如 logWhere2)。在查找對話框,點擊Find All in Current Document。這將僅顯示與日誌名稱前綴匹配的行。