// [snippet:Implementing dynamic operator] // Rreference C# implementation of dynamic operations #r "Microsoft.CSharp.dll" open System open System.Runtime.CompilerServices open Microsoft.CSharp.RuntimeBinder // Simple implementation of ? operator that works for instance // method calls that take a single argument and return some result let (?) (inst:obj) name (arg:'T) : 'R = // TODO: For efficient implementation, consider caching of call sites // Create dynamic call site for converting result to type 'R let convertSite = CallSite>.Create (Binder.Convert(CSharpBinderFlags.None, typeof<'R>, null)) // Create call site for performing call to method with the given // name and a single parameter of type 'T let callSite = CallSite>.Create (Binder.InvokeMember ( CSharpBinderFlags.None, name, null, null, [| CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null); CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null) |])) // Run the method call using second call site and then // convert the result to the specified type using first call site convertSite.Target.Invoke (convertSite, callSite.Target.Invoke(callSite, inst, arg)) // [/snippet] // [snippet:Example of using the operator] // Dynamically invoke 'Next' method of 'Random' type let o = box (new Random()) let a : int = o?Next(10) // [/snippet]