Getting started
Installing
Important
Install 7.0.0 (netstandard2.0 + net10.0, Dynamitey.Community 4.0.0). This is the last release that supports .NET Standard 2.0, which is .NET Framework 4.6.1 through 4.8.1. 6.0.0 was the same target frameworks on Dynamitey 3.0.3. 5.0.1.268 is the previous TFM set (net45 / netstandard1.6 / netstandard2.0).
dotnet add package FSharp.Interop.Dynamic
<PackageReference Include="FSharp.Interop.Dynamic" Version="7.0.0" />
open FSharp.Interop.Dynamic
open FSharp.Interop.Dynamic.Operators // optional: ?+?, ?=?, …
open FSharp.Interop.Dynamic brings in the auto-opened ?, ?<-, and !? operators. The Dyn module is always there; you do not need a second open for it.
The three operators you actually use
| Operator | Meaning |
|---|---|
target?Name |
Get a property, or call a method (the result can be a function you then apply) |
target?Name <- value |
Set a property |
!?target |
Invoke target itself (an F# function boxed as obj, a delegate, a Dynamitey curry) |
open System.Dynamic
let o = ExpandoObject()
o?Name <- "Ada"
let name: string = o?Name
let parts: string[] = "a,b,c"?Split(',')
Annotate the result type when F# cannot infer it. The DLR conversion uses that type.
Why not just use C# dynamic from F#?
You can, with a C# helper, and for a member whose name is a literal in C# that is often simpler. Reach for this library when:
- The call is in F#. There is no
dynamickeyword.?is the F# spelling. - The name is data.
o?Namestill writesNamein source;Dyn.get name otakes a string. - You want F# piping.
target |> Dyn.get "Name",target |> Dyn.tryGet "Name". - You want an option, not an exception.
Dyn.tryGet/Dyn.exists— see tryGet and exists. C#dynamichas no equivalent.
Infer the result, or you get obj
let n: int = "hello"?Length // 5
let boxed = "hello"?Length // obj, because nothing asked for int
Methods that return unit (void in CLR) need that annotation too, or the binder asks for a value from a void member and throws:
let items = ResizeArray<string>()
let _: unit = items?Add("x")
Where to go next
- Why this library — untyped payloads, optional fields, names as data, C#
dynamic - Operators —
?,?<-,!?in detail - Dyn — the functions behind those operators
- tryGet and exists — the issue #27 surface
- Caveats — explicit interface members, AOT, conversion vs missing, 15-arg, optionals, null target