Использование пользовательского оператора, как предполагает 'kvb', безусловно, вариант. Другой подход, который может вас заинтересовать в этом случае, состоит в том, чтобы определить собственное «вычислительное выражение», которое автоматически выполняет проверку значения null
в каждой указанной вами точке. Код, который использует его, будет выглядеть так:
open System.Windows.Forms
// this function returns (0) null, or (1) btn whose parent is
// null or (2) button whose parent is not null
let test = function
| 1 -> new Button(Text = "Button")
| 2 -> new Button(Text = "Button", Parent = new Button(Text = "Parent"))
| _ -> null
let res =
safe { let! btn = test(2) // specify number here for testing
// if btn = null, this part of the computation will not execute
// and the computation expression immediately returns null
printfn "Text = %s" btn.Text
let! parent = btn.Parent // safe access to parent
printfn "Parent = %s" parent.Text // will never be null!
return parent }
Как вы можете видеть, когда вы хотите использовать значение, которое потенциально может быть 'нулевым', вы используете let!
внутри выражения вычисления. Выражение вычисления может быть определено так, что оно немедленно возвращает null
, если значение равно null
, и выполняет остальную часть вычисления в противном случае. Вот код:
type SafeNullBuilder() =
member x.Return(v) = v
member x.Bind(v, f) =
if v = null then null else f(v)
let safe = new SafeNullBuilder()
Кстати: если вы хотите узнать больше об этом, это очень похоже на монаду «Maybe» в Haskell (или вычисления, работающие с опцией типа F #).