#f#
#f#
Вопрос:
учитывая следующее различаемое объединение:
type A = B of string | C of int
Как я могу получить имя конструктора B?
A.B.ToString()
// would return something like:
val it : string = "FSI_0045 it@109-19"
// when I desire
val it : string = "B"
например, с этим типом это работает:
type D = E | F
D.E.ToString();;
val it : string = "E"
Обычно я получаю строковое имя экземпляра DU с помощью
let stringFromDU (x: 'a) =
match FSharpValue.GetUnionFields(x, typeof<'a>) with
| case, _ -> case.Name
Но в этом случае у меня нет экземпляра, я просто хочу сериализовать имя метки.
Ответ №1:
Если вы включаете последнюю версию языка, например, путем перехода --langversion:preview
в FSI или настройки
<PropertyGroup>
<LangVersion>preview</LangVersion>
</PropertyGroup>
в вашем .fsproj
случае будет работать следующее:
type A = B of int
let n = nameof A.B
Примечание: с F # 5 это будет поддерживаться из коробки 🙂
Комментарии:
1. Спасибо! это должно быть то, что я хочу, однако я все еще не использую предварительный просмотр, поскольку он пока нестабилен. Я использую это:
fsharp let rec funName = function | Patterns.NewUnionCase (x, _) -> x.Name | Patterns.Call (None, methodInfo, _) -> methodInfo.Name | Patterns.Lambda (_, expr) -> funName expr | _ -> failwith "Unexpected input" <@ A.B @> |> funName
Я переключусь наnameof
после того, как F # 5 выйдет. Я нашел это немного плохим, так как я должен предоставить функцию сбоя — .-2. @CodingEdgar Вы можете использовать функции предварительного просмотра с текущим 4.7 … для меня пока никаких проблем 🙂
3. Я попробую и свяжусь с вами, если все скомпилируется, спасибо!
4. Использовал ваш подход, все скомпилировалось и работало как шарм, спасибо.
Ответ №2:
FSharpValue
В вашем примере вы используете FSharp.Reflection
пространство имен from . Обратите внимание, что в этой библиотеке есть другой класс для обработки сценариев, в которых вы хотите работать только с типами, FSharpType
.
let cases = FSharpType.GetUnionCases(typeof<A>)
Помимо объединений, он также предоставляет помощников для других операций с собственными типами F #.
Комментарии:
1. Да, я использую это для преобразования из string в DU, но я не могу получить имя случая DU с помощью этого, как, я думаю, в желаемом примере выше.
2. Он может дать вам имена всех случаев, но вы правы, он не позволит вам перейти от конструктора случая объединения к его имени. Цитаты были бы правильным инструментом здесь, так, как вы используете их сейчас.