FSharp.Interop.Dynamic

F# operators and helpers for the Dynamic Language Runtime. target?Name, target?Name<-value, and !?target do what C#'s dynamic keyword does, with F# inference and piping.

This is the fsprojects library that sits on Dynamitey 3.0.3. It is not Dynamitey itself; it is the F# surface.

Important

6.0.0 is the current package (netstandard2.0 and net10.0). 5.0.1.268 was the last package that still targeted net45 / netstandard1.6.

Where to start

If you want to Read
Know when to reach for this Why this library
Install and make the first ? call Getting started
Get, set, and invoke through the operators Operators
Pipe through Dyn.get / Dyn.invokeMember Dyn
Check a member without throwing tryGet and exists
Dynamic +, *, comparisons Binary operators
Turn a quotation into a member name Quotations
How this relates to Dynamitey 3.0.3 / 4.0.0 Dynamitey
What the DLR will not do Caveats
Cut a NuGet release Releasing
Look up a specific type or member API reference

The shortest example

open FSharp.Interop.Dynamic
open System.Dynamic

let o = ExpandoObject()
o?Name <- "Ada"
let name: string = o?Name

That is a DLR get/set. The compiler does not need to know Name. The same operators work on ViewBag, COM, pythonnet, SignalR clients, and ordinary CLR objects.

What this library is for

F# has no dynamic keyword. This library is that keyword, plus piping and an option-returning lookup.

  • The call is in F#. ? / ?<- / !? are the spelling.
  • The name is data. Dyn.get name takes a string; o?Name still writes Name in source.
  • You want an option, not an exception. Dyn.tryGet / Dyn.exists catch binder misses. C# dynamic has no equivalent.
  • You want F# piping. Target is last on Dyn.* so o |> Dyn.get "Name" works.

Reach for ordinary F# when the member is known at compile time. Reach for this library when it is not.

Supported frameworks

netstandard2.0 and net10.0. The netstandard2.0 target is kept deliberately — it is the only target reaching both .NET Framework 4.6.2+ and modern .NET from a single package. 6.0.0 dropped net45 and netstandard1.6.

A word on trimming and AOT

This library is DLR-based and will never be trim-safe or NativeAOT-safe. Members it resolves at runtime can disappear under the trimmer. See Caveats.