Skip to content

Instantly share code, notes, and snippets.

@vbfox
Created July 17, 2018 13:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vbfox/86be0025faa8d3702d8272bad0d6fa07 to your computer and use it in GitHub Desktop.
Save vbfox/86be0025faa8d3702d8272bad0d6fa07 to your computer and use it in GitHub Desktop.
F# dynamic
// dynamic x = "Foo";
// Console.WriteLine(x.ToString());
open System
open System.Runtime.CompilerServices
open Microsoft.CSharp.RuntimeBinder
let mutable toStringSite: CallSite<Func<CallSite, obj, obj>> option = None
let mutable writelineSite: CallSite<Action<CallSite, Type, obj>> option = None
type Marker() = class end
let x = "Foo" :> obj
if writelineSite = None then
let typeFromHandle = typeof<Marker>
let args = Array.zeroCreate<CSharpArgumentInfo> 2
args.[0] <- CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.UseCompileTimeType ||| CSharpArgumentInfoFlags.IsStaticType, null)
args.[1] <- CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null)
writelineSite <- Some (CallSite<Action<CallSite, Type, obj>>.Create(Binder.InvokeMember(CSharpBinderFlags.ResultDiscarded, "WriteLine", null, typeFromHandle, args)))
if toStringSite = None then
let typeFromHandle = typeof<Marker>
let args = Array.zeroCreate<CSharpArgumentInfo> 1
args.[0] <- CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null)
toStringSite <- Some (CallSite<Func<CallSite, obj, obj>>.Create(Binder.InvokeMember(CSharpBinderFlags.None, "ToString", null, typeFromHandle, args)))
let target = writelineSite.Value.Target
target.Invoke(writelineSite.Value, typeof<Console>, toStringSite.Value.Target.Invoke(toStringSite.Value, x))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment