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

原文在此優化

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

原linq語句:this

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

 

擴展方法:spa

        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方法。它能夠選擇打印經過此操做的全部項目和總數。code

  • logName是每一個輸出的前綴,能夠輕鬆查看編寫它的查詢步驟。我喜歡將其命名爲以後操做相同的名稱。blog

  • Fun<T,string>printMethod容許打印給定項目的任何內容。在上面的示例中,我選擇使用 e=>e.Name打印員工的姓名,當爲 null時,除總數外,不會打印任何內容。get

  • 爲了優化,此方法盡在調試模式下有效( #if DEBUG)。在發佈模式下,它什麼都不作。string

  • 每一個項目都按順序打印,無需等待操做結束,這是由於LINQ的 lazy 特性。如下是查看單個操做結果的提示:將整個輸出複製到 notepad++。而後使用Ctrl+Shift+F(Find)並查找日誌前綴(例如 logWhere2)。在查找對話框,點擊Find All in Current Document。這將僅顯示與日誌名稱前綴匹配的行。it

相關文章
相關標籤/搜索