Как сделать typeof модуля в файле fsx? - PullRequest
2 голосов
/ 26 мая 2010

Допустим, у меня есть сценарий Foo.fsx, который содержит этот код:

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

Как мне этого добиться?Спасибо!

1 Ответ

4 голосов
/ 27 мая 2010

Это сложный вопрос, потому что интерактивный F # компилирует все типы в типы с некоторыми искаженными именами (а исполняющая сборка может содержать несколько версий одного типа).

Мне удалось сделать это с помощью простого трюка - вы бы добавили в модуль дополнительный тип - тогда вы можете использовать typeof<..>, чтобы получить информацию об этом типе. Тип внутри модуля компилируется как вложенный тип, поэтому вы можете получить имя типа, представляющего модуль, из этого (вложенного) типа:

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, [| |])

Вероятно, вы можете просто найти все типы в сборке в поисках +Bar. Это бы сработало. Преимущество описанного выше трюка заключается в том, что вы получаете ссылку на конкретную версию типа (если вы в интерактивном режиме выполняете код несколько раз, вы получите ссылку на модуль, соответствующий текущему типу Bar.A)

В качестве дополнительного примечания были некоторые обсуждения о поддержке moduleof<Bar> (или что-то в этом роде) в будущих версиях F # - это немного не элегантно, поскольку это не реальная функция / значение, подобное typeof, но это было бы очень полезно!

...