Skip to content

Instantly share code, notes, and snippets.

@pirrmann
Created September 19, 2016 13:00
Show Gist options
  • Save pirrmann/2266af34aabe90cfaec3212be287ca6c to your computer and use it in GitHub Desktop.
Save pirrmann/2266af34aabe90cfaec3212be287ca6c to your computer and use it in GitHub Desktop.
F# Dynamic property get with null values
open FSharp.Interop.Dynamic
open Dynamitey
let dynamicPropertyGet<'TResult> (name:string) (target:obj) : 'TResult option =
let resultType = typeof<'TResult>
let (|NoConversion| Conversion|) t = if t = typeof<obj> then NoConversion else Conversion
let convert r = match resultType with | NoConversion -> r | _ -> dynImplicit(r)
match target with
| null -> None
| _ ->
let v = Dynamic.InvokeGet(target, name)
if isNull v then None
else v |> convert |> unbox |> Some
[<AllowNullLiteral>]
type Person (name:string, father:Person, mother:Person) =
member val Name = name
member val Father = father
member val Mother = mother
override this.ToString() = sprintf "%s, Father = %s, Mother = %s" this.Name (match this.Father with | null -> "(null)" | _ -> this.Father.Name) (match this.Mother with | null -> "(null)" | _ -> this.Mother.Name)
let adam = new Person("Adam", null, null)
let eve = new Person("Eve", null, null)
let cain = new Person("Caïn", adam, eve)
let abel = new Person("Abel", adam, eve)
let seth = new Person("Seth", adam, eve)
let azura = new Person("Azura?", null, null)
let enoch = new Person("Enosh", seth, azura)
let emptyIfNull x = match x with | null -> "" | _ -> x
let test =
enoch
|> dynamicPropertyGet<Person> "Father"
|> Option.bind (dynamicPropertyGet<Person> "Father")
|> Option.bind (dynamicPropertyGet<string> "Name")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment