2

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!

elmattic
  • 12,046
  • 5
  • 43
  • 79
  • 1
    FSI doesn't play nice with namespaces either (http://stackoverflow.com/questions/2354984/f-namespaces-modules-fs-and-fsx) – Benjol May 27 '10 at 06:16
  • Cross reference: [related question](http://stackoverflow.com/q/2297236) – Benjol Feb 05 '13 at 12:44

1 Answers1

4

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!

Tomas Petricek
  • 240,744
  • 19
  • 378
  • 553