2013-04-08 25 views
9

io sono abituato a scrivere codice come questo in C#:Come scrivere questo codice C# in F #

SomeObj obj; 
try{ 
    // this may throw SomeException 
    obj = GetSomeObj(); 
}catch(SomeException){ 
    // Log error... 
    obj = GetSomeDefaultValue(); 
} 

obj.DoSomething(); 

Questo è il modo in cui ho tradotto in F # (obj essendo una lista):

let mutable obj = [] 
try 
    obj <- getSomeObj 
with 
    | ex -> 
     // Log ex 
     obj <- getSomeDefaultValue 

doSomething obj 

C'è un modo per farlo in F # senza usare una variabile mutabile? C'è un modo più "elegante" per gestire questa situazione in F #?

Grazie!

risposta

20

Il modo -ish F # è quello di restituire lo stesso tipo di espressione in entrambi i rami:

let obj = 
    try 
     getSomeObj() 
    with 
    | ex -> 
     // Log ex 
     getSomeDefaultValue() 

doSomething obj 

in F #, è possibile gestire le eccezioni utilizzando option tipo. Questo è un vantaggio quando non c'è un valore predefinito ovvio e il compilatore ti obbliga a gestire casi eccezionali.

let objOpt = 
    try 
     Some(getSomeObj()) 
    with 
    | ex -> 
     // Log ex 
     None 

match objOpt with 
| Some obj -> doSomething obj 
| None -> (* Do something else *) 
+0

Grande! Sapevo che ci doveva essere un modo per farlo in un modo F # -ish! Sto imparando F # e non mi sono ancora abituato a pensare in modo funzionale. Grazie! –

8

Wrapping questa logica nelle funzioni ...

let attempt f = try Some(f()) with _ -> None 
let orElse f = function None -> f() | Some x -> x 

... potrebbe essere:

attempt getSomeObj |> orElse getSomeDefaultValue 
+0

Sebbene abbia scelto un'altra risposta utente valida, mi piace molto il modo in cui è stato scritto 'attempt'. Non ho mai pensato di scrivere qualcosa del genere. Grazie! –

+0

Prego. la risposta di pad illustra il punto cruciale della soluzione: tutto è un'espressione in F #, ma volevo sottolineare i modelli coinvolti. I primitivi come questi possono essere utili e portare a volte codice più leggibile. – Daniel