dictionary - 如何从 FSharp 中的反射调用 Map.Add?

标签 dictionary reflection f#

鉴于 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")|])

最后一行产生此错误:

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

即使您切换 intstring 参数,也会出现此错误。

有趣的是,下面的代码可以工作:

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")|])

那么如何从反射中有效地调用 Map.Add 呢?

最佳答案

找到了。

这一行:

let mymap = mt.MakeGenericMethod([|typeof<string>; typeof<string>|]).Invoke(null, [||])

应该是:

let mymap = mt.MakeGenericMethod([|typeof<int>; typeof<string>|]).Invoke(null, [||])

类型不匹配实际上是真实的,因为使用不正确的泛型类型调用了“Empty”方法。

所以这最终是正确的代码:

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 am = mm.GetMethod("Add", BindingFlags.Static ||| BindingFlags.Public)
let mymap = mt.MakeGenericMethod([|typeof<int>; typeof<string>|]).Invoke(null, [||])
let addmethod = typeof<Mapping>.GetMethod("Add")

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

关于dictionary - 如何从 FSharp 中的反射调用 Map.Add?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47223975/

相关文章:

python - FOR 循环应该产生多个结果,但只产生一个

swift - Type (key : String, value: Any) 没有下标成员

.net - 在 .NET (F#) 中使用可替换的后端实现来实现 API

f# - 将 app.config 中的连接字符串与 FSharp.Data.SqlClient 结合使用

f# - 团结, Prism ,FSharp

python - 在 cython : memoryview vs vector of dictionaries 中快速访问稀疏矩阵

python - 以字典作为可选参数的函数 - Python

reflection - 在 Windows Phone 7 上获取汇编版本

c# - 仅使用类型的类型制作编译的构造函数表达式

.net - 无法从 .winmd 文件获取类型