Created
September 19, 2016 13:00
-
-
Save pirrmann/2266af34aabe90cfaec3212be287ca6c to your computer and use it in GitHub Desktop.
F# Dynamic property get with null values
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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