2013-04-08 5 views
9

F#で、このC#コードの書き方:私はC#で、このようなコードを書くために使用しています

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

doSomething obj 
:(リストであるobjを)

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

obj.DoSomething(); 

これは私がF#で、それを翻訳方法があるが

可変変数を使用せずにF#でこれを行う方法はありますか? F#でこの状況を処理するためのよりエレガントな方法はありますか?

ありがとうございました!

答えて

20

F#-ishの方法は、両方のブランチで表現の同じ型を返すことです: は

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

doSomething obj 

F#では、あなたがoptionタイプを使用して例外を処理することができます。これは明白なデフォルト値がなく、コンパイラが例外的なケースを処理することを強いる場合に有利です。

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

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

グレート!私はこれをF#のようにする方法がなければならないことを知っていました! 私はF#を学んでいますが、私はまだ機能的な方法で考えるのに慣れていません。ありがとうございました! –

8

ラッピング機能では、このロジック...

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

...それは次のようになります。

attempt getSomeObj |> orElse getSomeDefaultValue 
+0

私はいくつかのユーザーの回答を有効と選択しましたが、私は実際には「試行」が書かれた方法が好きです。私はそのようなことを書くことについて決して考えなかった。 ありがとうございます! –

+0

ようこそ。パッドの答えは、ソリューションの要点を示しています。すべてがF#の表現ですが、関連するパターンを指摘したいと思いました。このようなプリミティブは便利なことがあり、時にはより読みやすいコードにつながります。 – Daniel

関連する問題