F # Получить элементы модуля

#reflection #module #f# #member

#отражение #модуль #f# #Участник

Вопрос:

Учитывая

 type Unit = {
            Name : string
            Abbreviation : string
            Value : float
        }

module Lets =
    let meter = { Name = "meter"; Abbreviation = "m"; Value = 1.0 }
    let millimeter = { Name = "millimeter"; Abbreviation = "mm"; Value = 1e-3 }
  

Как я могу создать функцию с этой подписью?

 let units () : Units[] = ...
  

Ответ №1:

Модули F # являются просто статическими классами при компиляции.

Используя отражение, вы должны иметь возможность получать эти значения примерно так:

 module Lets =
    type Dummy = | Dummy
    let meter = { Name = "meter"; Abbreviation = "m"; Value = 1.0 }
    let millimeter = { Name = "millimeter"; Abbreviation = "mm"; Value = 1e-3 }


let t = typeof<Lets.Dummy>.DeclaringType
t.GetProperties() |> Array.map(fun p -> p.GetValue(null, null) :?> Unit)
  

Сложно получить тип модуля, но этот трюк сделает это за вас.

Редактировать:

Обновлено для приведения непосредственно к Unit . Приведение, как показано, небезопасно и будет выдавать, если GetValue не возвращает Unit тип.

Кроме unit того, это тип в F #, возможно, было бы понятнее использовать другое имя.

Комментарии:

1. Очень хорошо. Я отредактировал свой ответ, чтобы включить определение Unit типа и что я хочу вернуть Units[] вместо obj[] .

2. В этом случае вам придется жестко привести к a Units , я соответствующим образом обновлю свой ответ