2012-11-01 14 views
0

說我有這樣的一些語句:有什麼辦法可以捕獲導致異常的LINQ中的謂詞?

List<string> list = new List<string> {"1", "1", "2", "3", "4"}; 
try 
{ 
    Class1 c = new Class1 
     { 
      s1 = list.Single(s => s == "1"), 
      s2 = list.Single(s => s == "2"), 
      s3 = list.Single(s => s == "3"), 
      s4 = list.Single(s => s == "4") 
     }; 
} 
catch (InvalidOperationException ex) 
{ 
    Console.WriteLine(ex.Message); 
} 

我肯定會去的catch塊有錯誤「輸入序列包含多個元素」在這一行:

s1 = list.Single(s => s == "1") 

所以,我只是好奇,它有什麼方法可以在catch塊中顯示錯誤謂詞?如果我們看到類似「有重複元素」1「的順序,這對修復錯誤非常有用。」甚至是字符串格式的完整謂詞。我能以某種方式查看這些信息並顯示或記錄它嗎?

+0

那麼,例外已經包含它發生的行不是嗎? –

+0

你能夠附加一個調試器,或者它是用於「生產」日誌目的嗎? – Allov

+0

@布萊恩拉斯穆森,是的,你說得很對,我只是試了一下。我想這是使用可能拋出的初始化列表的問題。如果您將初始化移動到Class1的構造函數,您將獲得行號。 –

回答

4

如果你真的需要有關謂詞的信息和它的參數,那麼你就可以創建自己的Single擴展方法(它會被調用,而不是默認的方法),這實際上將包裹默認Single通話,但它會收到Expression(表達樹表示lambda表達式)而不是Func(lambda表達式):

public static T Single<T>(this IEnumerable<T> sequence, 
          Expression<Func<T, bool>> predicate) 
{ 
    try 
    { 
     return sequence.Single(predicate.Compile()); 
    } 
    catch (InvalidOperationException ex) 
    { 
     Console.WriteLine("Error on predicate " + predicate); 
     throw; 
    }    
} 

在線s1 = list.Single(s => s == "1")將拋出異常和寫入相當錯誤消息:

Error on predicate s => s == "1"

+0

雖然這會工作,但我不確定我喜歡「隱藏」這樣的默認操作。這與你必須隱藏所有重載和所有其他Linq擴展的事實相結合,它似乎太狹窄的範圍被認爲是一個好的解決方案。這是聰明的,但:) :) –

+0

@DStanley謝謝!我也更好地從在線初始化切換,並收到一個很好的堆棧跟蹤。但如果由於某種原因不可能,並且參數信息非常重要,那麼表達式樹是一個不錯的選擇。也可能OP只有'單一'的方法有問題。 –

-1
List<string> list = new List<string> {"1", "1", "2", "3", "4"}; 
string sValue=null; 
try 
{ 
    sValue="1"; 
    Class1 c = new Class1 
    { 
     s1 = list.Single(s => s == sValue), 

    }; 
} 
catch (InvalidOperationException ex) 
{ 
    Console.WriteLine("s => s == "+ sValue); 
} 
+0

這不是對象初始值設定項的有效語法。 –

+0

你如何期待這個工作? –

+0

修復了syntax.sorry。 @lazyberezovsky方法很好 – Frank59

2

不,拋出的異常(InvalidOperationException)是通用的,不會給出這種細節。堆棧跟蹤將從Single()開始,而不顯示傳入的謂詞。

如果您需要該級別的詳細信息,可以在單獨的語句中設置屬性,以便可以從堆棧跟蹤中獲取行號,或者您可以對數據進行「預先檢查」以確保其符合您的獨特條件。

相關問題