How to do typeof of a module in a fsx file?

老子叫甜甜 提交于 2019-12-24 01:58:09

问题


Let's say I have a Foo.fsx script that contains this code:

module Bar =
  let foobar = "foo"+"bar"

open Bar
let a = System.Reflection.Assembly.GetExecutingAssembly()
let ty = a.GetType("Foo.Bar") // but it returns null here

How can I achieve that? Thanks!


回答1:


This is a tricky question, because F# interactive compiles all types into types with some mangled names (and the executing assembly can contain multiple versions of the same type).

I managed to do it using a simple trick - you'd add an additional type to the module - then you can use typeof<..> to get information about this type. The type inside a module is compiled as a nested type, so you can get the name of the type representing the module from this (nested) type:

module Bar = 
  let foobar = "foo"+"bar" 
  type A = A

// Get type of 'Bar.A', the name will be something like "FSI_0001+Bar+A",
// so we remove the "+A" from the name and get "FSI_0001+Bar"
let aty = typeof<Bar.A>
let barName = aty.FullName.Substring(0, aty.FullName.Length - "+A".Length)
let barTy = aty.Assembly.GetType(barName)

// Get value of the 'foobar' property - this works!
barTy.GetProperty("foobar").GetValue(null, [| |])

You could probably simply search all types in the assembly looking for +Bar. That would work as well. The benefit of the trick above is that you get a reference to the specific version of the type (if you interactively run the code multiple times, you'll get a reference to the module corresponding to the current Bar.A type)

As a side-note, there were some discussions about supporting moduleof<Bar> (or something like that) in future versions of F# - this is a bit inelegant as it is not a real function/value like typeof, but it would very useful!



来源:https://stackoverflow.com/questions/2916294/how-to-do-typeof-of-a-module-in-a-fsx-file

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!