Home > Blockchain >  Converting F# functions to System.Func causes "System.Reflection.TargetException : Non-static m
Converting F# functions to System.Func causes "System.Reflection.TargetException : Non-static m

Time:06-29

I'd like to get MethodInfo for caller-provided functions.

module MethodInfo = 
    let from0 (f: unit -> 'a) = (Func<'a>(f)).Method
    let from1 (f: 'a -> 'b) = (Func<'a,'b>(f)).Method

let mi = MethodInfo.from0 (fun () -> 5)
mi.Invoke(null, Array.empty<obj>)

This compiles, but always throws "System.Reflection.TargetException : Non-static method requires a target."

The exception is not thrown if I pass an anonymous function directly to a method.

type MethodInfo =
    static member from0 (f:Func<'a>) = f.Method
    static member from1 (f:Func<'a,'b>) = f.Method

MethodInfo.from0 (fun () -> 5)
mi.Invoke(null, Array.empty<obj>)

Why does the conversion from F# functions to Func cause this exception? Is there a better way to get MethodInfo (some update since this old thread)?

CodePudding user response:

The issue is that the method returned by the delegate is not a static method, but an instance method that has to be invoked on an object that represents the closure (the object would normally capture e.g. variables that are used inside the function but are defined in the outer scope).

You can get your code to work if you return both the MethodInfo and the target object of the delegate. Then you can pass the target object to Invoke and you get back the expected result:

open System

module MethodInfo = 
  let from0 (f: unit -> 'a) = 
    let del = Func<'a>(f)
    del.Target, del.Method

let target, mi = MethodInfo.from0 (fun () -> 5)
mi.Invoke(target, Array.empty<obj>)
  • Related