2011-07-07 6 views
12

Me trataron de capturar una excepción, pero el compilador da advertencia: Esta prueba tipo o abatido siempre tendrá¿Cómo atrapar cualquier excepción (System.Exception) sin una advertencia en F #?

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

La pregunta es: ¿cómo lo hago sin la advertencia? (Creo que tiene que haber una manera de hacer esto, de lo contrario no debería haber ningún aviso)

Al igual que C#

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

Su ejemplo de C# provoca una advertencia para cualquiera que use ReSharper o FxCop. [¿Por qué?] (Http://blogs.msdn.com/b/codeanalysis/archive/2006/06/14/631923.aspx) –

+1

@Joel Mueller, gracias por su artículo. Tampoco me gusta atrapar la excepción general, pero a veces una excepción inesperada puede confundir a los usuarios. – LLS

Respuesta

26

C#:

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

F # equivalentes:

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 # equivalente:

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 # equivalente:

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

Como notó Joel, no querrá usar catch (Exception) en C# por el mismo motivo por el que no usa | :? System.Exception -> en F #.

+0

Gracias. Eso es muy detallado. Después de leer el comentario de Joel, intentaré evitar la excepción general. Pero creo que a veces puede ser necesario fallar con gracia ... (Al menos dar mensajes de error de manera fácil de usar) – LLS

+1

@LLS: No es que atrapar el tipo base de 'Excepción' sea necesariamente un problema, es que 'atrape (Excepción) {} 'y' catch {} 'tienen una semántica idéntica, por lo que la primera es redundante y produce una advertencia. Si _name_ el objeto de excepción, 'catch (Exception ex) {}', no hay advertencia. – ildjarn

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

No sabía que podía alias la coincidencia de comodines así. Eso es realmente útil (y no solo para el manejo de excepciones) – piers7

+0

El '_' es realmente redundante, y en realidad este código socava el propósito de la variable' _' '| _ como e -> (...) ' no hace nada diferente de ' | e -> (..) ' cualquier var sin cláusula de protección en una declaración de coincidencia de patrón es un todo, nombrando la variable' _' simplemente indica que no le importa el valor. Aliasing el tipo '_' socava el' _' en primer lugar. – Vidar

Cuestiones relacionadas