Как я могу использовать отражение, чтобы определить, является ли тип объединения F # союзом типа enum (нет полей в каждом случае) - PullRequest
0 голосов
/ 25 января 2019

Терминология

В следующем посте я буду использовать термин «ссылочное перечисление» для обозначения типа F #, который является дискриминационным объединением без полей в каждом случае. Например:

type AReferenceEnum = Yes | No | Maybe

Требования

Мне нужна функция, которая дает Type, возвращает bool, который сообщает, является ли тип ссылочным перечислением или нет.

С учетом этих типов:

type AReferenceEnum = Yes | No | Maybe

type ARecord = { name : string }

type AUnion = This of int | That of (int * string)

type AEnum = Left = 1 | Right = 2

Функция будет возвращать эти значения

isReferenceEnum typeof<AReferenceEnum> -> true

isReferenceEnum typeof<ARecord> -> false

isReferenceEnum typeof<AUnion> -> false

isReferenceEnum typeof<AEnum> -> false

Что я пробовал

Похоже, что реализация может быть выполнена с использованием FSharpType и FSharpValue в пространстве имен FSharp.Reflection.

Я знаю, что вы можете проверить FSharpType.IsUnion t, чтобы проверить, является ли тип объединением, которое включает ссылочные перечисления.

Я знаю, что вы можете проверить FSharpType.GetUnionCases t, чтобы получить UnionCaseInfo[], описывающий различные случаи типа объединения.

Я знаю, что вы можете проверить FSharpValue.GetUnionFields (value, type), чтобы получить поля для случая, в котором value является экземпляром, но не для других случаев.

Если бы я мог повторять поля каждого случая объединения, то я мог бы проверить, что во всех случаях есть 0 полей, и тогда тип был бы ссылочным перечислением.

Есть предложения?

1 Ответ

0 голосов
/ 25 января 2019

Это проходит ваши тесты:

let isReferenceEnum ty = 
    if FSharpType.IsUnion ty then
        FSharpType.GetUnionCases ty
        |> Array.forall (fun i -> i.GetFields().Length = 0)
    else
        false
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...