2014-01-08 27 views
0

我調試這行代碼:調試外部調用Lambda表達式

var myDict = myEnumerable.ToDictionary(k => k.NumericValue, v => v.Display()); 

我得到一個ArgumentException (An item with the same key has already been added)

VS2012似乎沒有提供關於k.NumericValue導致重複密鑰的值的見解。

我當然可以通過編寫一些額外的調試代碼來獲得重複鍵來解決這個問題,但是有沒有辦法直接從調試器中獲取?

回答

2

你不會有ToDictionary的符號信息,而且我更懷疑.NET BCL是以調試模式編譯的......所以不會。

當然,如果您編寫自己的ToDictionary實施方案,您可以提供例外情況中的信息,或者可以在信息可用的地方中斷。

雖然在技術上可能檢查內存的各種狀態以確定程序運行時的密鑰是什麼,但它將會變得更簡單隻需稍微更改代碼即可診斷此問題問題。

+0

你說得對。如果Watch支持lambda表達式,這將是可能並且微不足道的,但是添加一行代碼如myEnumerable.GroupBy(e => e.NumericValue,e => e.NumericValue).Where(grp => grp。 Count()> 1)。選擇(grp => grp.First())'並檢查結果。 –

+0

通常情況下,我只是改變了代碼並繼續前進,但該過程運行了很長一段時間,然後才遇到該情況,因此它讓我考慮是否有更好的方法。如果可以在拋出ArgumentException的時候在調試器中檢查'k',那就可以解決問題。 –

+0

@SimonBelanger你可以讓調試器在lambda上中斷,問題是lambda已經在拋出異常的時候完成執行,所以當出現異常時,通過拉姆達;在庫代碼中只有一個本地存儲結果,因此您需要能夠在ToDictionary的定義中檢查該本地,這是無法完成的。 – Servy

0

Servy的回答是正確的問題我問。

解決方案是編寫自定義代碼進行調試。這是我寫入的一個擴展方法,作爲ToDictionary()的插入式替換,它引發了一個更有意義的異常。隨意編輯和改進。

public static Dictionary<K,V> ToDictionaryDbg<T,K,V>(this IEnumerable<T> source, Func<T,K> key, Func<T,V> value) 
{ 
    if (source == null) return null; 

    Dictionary<K, V> result = new Dictionary<K, V>(); 

    foreach (var element in source) 
    { 
     K k = default(K); 
     V v = default(V); 

     try 
     { 
      k = key(element); 
      v = value(element); 
      result.Add(k, v); 
     } 
     catch (ArgumentException aex) 
     { 
      throw new ArgumentException("Could not add element with key " + k + ". See inner exception.", aex); 
     } 
    } 

    return result; 
}