vendredi 10 novembre 2017

How to call Map.Add from reflection in FSharp?

Given the following code in the FSI:

type Mapping = Map<int,string>

let mm = [ for i in Assembly.GetAssembly(typeof<Mapping>).ExportedTypes do yield i]|> List.find(fun m -> m.Name.Contains("MapModule"))
let mt = mm.GetMethod("Empty", BindingFlags.Static ||| BindingFlags.Public)
let mymap = mt.MakeGenericMethod([|typeof<string>; typeof<string>|]).Invoke(null, [||])

let addmethod = typeof<Mapping>.GetMethod("Add")

addmethod.Invoke(mymap, [|box(1);box("astring")|])

The last line produces this error:

System.Reflection.TargetException: Object does not match target type. at System.Reflection.RuntimeMethodInfo.CheckConsistency(Object target) at System.Reflection.RuntimeMethodInfo.InvokeArgumentsCheck(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) at System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters) at .$FSI_0006.main@() Stopped due to error

Even when you switch the int and string parameters, it gives this error.

Funny thing though, the following code works:

type Mapping = Map<string,string>

let mm = [ for i in Assembly.GetAssembly(typeof<Mapping>).ExportedTypes do yield i]|> List.find(fun m -> m.Name.Contains("MapModule"))
let mt = mm.GetMethod("Empty", BindingFlags.Static ||| BindingFlags.Public)
let mymap = mt.MakeGenericMethod([|typeof<string>; typeof<string>|]).Invoke(null, [||])

let addmethod = typeof<Mapping>.GetMethod("Add")
addmethod.Invoke(mymap, [|box("a");box("b")|])

So how can I call Map.Add effectively from reflection?





Aucun commentaire:

Enregistrer un commentaire