2011-07-07 69 views
12

我試圖捕捉異常,但編譯器會發出警告:這種類型的測試或沮喪的總是擁有如何在F#中沒有警告的情況下捕獲任何異常(System.Exception)?

let testFail() = 
    try 
     printfn "Ready for failing..." 
     failwith "Fails" 
    with 
    | :? System.ArgumentException ->() 
    | :? System.Exception ->() 

的問題是:如何將我做沒有報警? (我相信一定有辦法做到這一點,否則應該沒有警告)

如C#

try 
{ 
    Console.WriteLine("Ready for failing..."); 
    throw new Exception("Fails"); 
} 
catch (Exception) 
{ 
} 
+1

您的C#示例會爲使用ReSharper或FxCop的任何人導致警告。 [爲什麼?](http://blogs.msdn.com/b/codeanalysis/archive/2006/06/14/631923.aspx) –

+1

@Joel Mueller,謝謝你的文章。我也不喜歡捕捉到一般的異常,但有時意外的異常可能會讓用戶感到困惑。 – LLS

回答

26

C#:

void testFail() 
{ 
    try 
    { 
     Console.WriteLine("Ready for failing..."); 
     throw new Exception("Fails"); 
    } 
    catch (ArgumentException) 
    { 
    } 
    catch 
    { 
    } 
} 

F#相當於:

let testFail() = 
    try 
     printfn "Ready for failing..." 
     failwith "Fails" 
    with 
    | :? System.ArgumentException ->() 
    | _ ->() 

C#:

void testFail() 
{ 
    try 
    { 
     Console.WriteLine("Ready for failing..."); 
     throw new Exception("Fails"); 
    } 
    catch (ArgumentException ex) 
    { 
    } 
    catch (Exception ex) 
    { 
    } 
} 

F#當量:

let testFail() = 
    try 
     printfn "Ready for failing..." 
     failwith "Fails" 
    with 
    | :? System.ArgumentException as ex ->() 
    | ex ->() 

C#:

void testFail() 
{ 
    try 
    { 
     Console.WriteLine("Ready for failing..."); 
     throw new Exception("Fails"); 
    } 
    catch 
    { 
    } 
} 

F#當量:

let testFail() = 
    try 
     printfn "Ready for failing..." 
     failwith "Fails" 
    with 
    | _ ->() 

正如Joel指出的那樣,您不希望在C#中使用catch (Exception),這與您在F#中不使用| :? System.Exception ->的原因相同。

+0

謝謝。這非常詳細。在閱讀喬爾的評論後,我會盡量避免捕捉到一般的例外。但我想有時候可能有必要優雅地失敗......(至少以用戶友好的方式給出錯誤信息) – LLS

+1

@LLS:這不是捕捉到基地'Exception'類型肯定是一個問題,它是'catch(例外){}'和'catch {}'具有相同的語義,所以前者是多餘的併產生警告。如果你_name_這個異常對象,catch(Exception ex){}',那麼沒有警告。 – ildjarn

3
try 
    .. code .. 
with 
    | _ as e -> 
+0

我不知道你可以像這樣的通配符匹配。這真的很方便(而不僅僅是用於異常處理) – piers7

+0

'_'實際上是多餘的,實際上這個代碼破壞了'_'變量的用途 '| | _ as e - >(...)' 沒有任何區別 '| | e - >(..)' 任何在模式匹配語句中沒有guard子句的var是一個catch all,命名變量'_'只是表示你不關心這個值。混淆'_'會首先破壞'_'。 – Vidar

相關問題