5 people like it.
Like the snippet!
Preempting NullReferenceExceptions
When interfacing .NET libraries that potentially yield null values, a lot of boilerplate code is required to ensure no NullReferenceExceptions are raised. This is an attempt to avoid such repetition with computation expressions.
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
|
/// strips values of reference types that are null
let strip<'T when 'T : null> (x : 'T) = match x with null -> None | x -> Some x
type DenullBuilder() =
member __.Return x = x
member __.Zero() = null
member __.Bind(x, f) = match x with null -> null | x -> f x
let denull = new DenullBuilder()
// example
open Microsoft.Win32
denull {
let bkey = RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, RegistryView.Default)
let! k1 = bkey.OpenSubKey(@"Software\Microsoft\VisualStudio\11.0")
let! k2 = k1.OpenSubKey(@"DialogPage\Microsoft.VisualStudio.FSharp.Interactive.FsiPropertyPage")
let! switch = k2.GetValue "FsiPreferAnyCPUVersion" :?> string
if switch = "True" then
return k2.GetValue "FsiCommandLineArgs" :?> string
} |> strip
|
val strip : x:'T -> 'T option (requires 'T : null)
Full name: Script.strip
strips values of reference types that are null
val x : 'T (requires 'T : null)
union case Option.None: Option<'T>
union case Option.Some: Value: 'T -> Option<'T>
Multiple items
type DenullBuilder =
new : unit -> DenullBuilder
member Bind : x:'a * f:('a -> 'b) -> 'b (requires 'a : null and 'b : null)
member Return : x:'d -> 'd
member Zero : unit -> 'c (requires 'c : null)
Full name: Script.DenullBuilder
--------------------
new : unit -> DenullBuilder
member DenullBuilder.Return : x:'d -> 'd
Full name: Script.DenullBuilder.Return
val x : 'd
val __ : DenullBuilder
member DenullBuilder.Zero : unit -> 'c (requires 'c : null)
Full name: Script.DenullBuilder.Zero
member DenullBuilder.Bind : x:'a * f:('a -> 'b) -> 'b (requires 'a : null and 'b : null)
Full name: Script.DenullBuilder.Bind
val x : 'a (requires 'a : null)
val f : ('a -> 'b) (requires 'a : null and 'b : null)
val denull : DenullBuilder
Full name: Script.denull
namespace Microsoft
namespace Microsoft.Win32
val bkey : RegistryKey
type RegistryKey =
inherit MarshalByRefObject
member Close : unit -> unit
member CreateSubKey : subkey:string -> RegistryKey + 4 overloads
member DeleteSubKey : subkey:string -> unit + 1 overload
member DeleteSubKeyTree : subkey:string -> unit + 1 overload
member DeleteValue : name:string -> unit + 1 overload
member Dispose : unit -> unit
member Flush : unit -> unit
member GetAccessControl : unit -> RegistrySecurity + 1 overload
member GetSubKeyNames : unit -> string[]
member GetValue : name:string -> obj + 2 overloads
...
Full name: Microsoft.Win32.RegistryKey
RegistryKey.OpenBaseKey(hKey: RegistryHive, view: RegistryView) : RegistryKey
type RegistryHive =
| ClassesRoot = -2147483648
| CurrentUser = -2147483647
| LocalMachine = -2147483646
| Users = -2147483645
| PerformanceData = -2147483644
| CurrentConfig = -2147483643
| DynData = -2147483642
Full name: Microsoft.Win32.RegistryHive
field RegistryHive.CurrentUser = -2147483647
type RegistryView =
| Default = 0
| Registry64 = 256
| Registry32 = 512
Full name: Microsoft.Win32.RegistryView
field RegistryView.Default = 0
val k1 : RegistryKey
RegistryKey.OpenSubKey(name: string) : RegistryKey
RegistryKey.OpenSubKey(name: string, permissionCheck: RegistryKeyPermissionCheck) : RegistryKey
RegistryKey.OpenSubKey(name: string, writable: bool) : RegistryKey
RegistryKey.OpenSubKey(name: string, permissionCheck: RegistryKeyPermissionCheck, rights: System.Security.AccessControl.RegistryRights) : RegistryKey
val k2 : RegistryKey
val switch : string
RegistryKey.GetValue(name: string) : obj
RegistryKey.GetValue(name: string, defaultValue: obj) : obj
RegistryKey.GetValue(name: string, defaultValue: obj, options: RegistryValueOptions) : obj
Multiple items
val string : value:'T -> string
Full name: Microsoft.FSharp.Core.Operators.string
--------------------
type string = System.String
Full name: Microsoft.FSharp.Core.string
More information