2013-04-08 21 views
9

ja jestem przyzwyczajony do pisania kodu jak to w C#:Jak napisać ten kod C# w F #

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

obj.DoSomething(); 

jest to sposób przetłumaczyłem go w F # (obj będąc listę):

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

doSomething obj 

Czy jest jakiś sposób, aby to zrobić w F # bez użycia zmiennej zmiennej? Czy istnieje bardziej "elegancki" sposób radzenia sobie z tą sytuacją w F #?

Dziękujemy!

Odpowiedz

20

F # -ish sposobem jest powrót do tego samego rodzaju ekspresji w obu branżach:

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

doSomething obj 

w F #, można obsługiwać za pomocą option wyjątki typu. Jest to zaleta, gdy nie ma oczywistej wartości domyślnej, a kompilator wymusza obsługę wyjątkowych przypadków.

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

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

Great! Wiedziałem, że musi być sposób, aby to zrobić w sposób F! Uczę się F # i wciąż nie przywykłem myśleć w sposób funkcjonalny. Dziękuję Ci! –

8

owijania ta logika w funkcji ...

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

... może to być:

attempt getSomeObj |> orElse getSomeDefaultValue 
+0

Chociaż wybrałem inną prawidłową odpowiedź dla użytkownika, bardzo podoba mi się sposób, w jaki napisano "próbę". Nigdy nie myślałem o napisaniu czegoś takiego. Dziękujemy! –

+0

Nie ma za co. Odpowiedzi padowe ilustrują sedno rozwiązania: wszystko jest wyrażeniem w języku F #, ale chciałem zwrócić uwagę na wzorce. Prymitywy takie jak te mogą być przydatne i czasami dają czytelniejszy kod. – Daniel