代码之家  ›  专栏  ›  技术社区  ›  Natalie Perret

如何获取F中给定联合类型的每个联合案例的类型#

  •  0
  • Natalie Perret  · 技术社区  · 5 年前

    在下面的F#代码中,我想知道如何通过反射获取与每个联合案例相关联的类型

    type AccountCreatedArgs = {
        Owner: string
        AccountId: Guid
        CreatedAt: DateTimeOffset
        StartingBalance: decimal
    }
    
    type Transaction = {
        To: Guid
        From: Guid
        Description: string
        Time: DateTimeOffset
        Amount: decimal
    }
    
    type AccountEvents =
        | AccountCreated of AccountCreatedArgs
        | AccountCredited of Transaction
        | AccountDebited of Transaction
    
    

    我试着用 FSharpType.GetUnionCases(typeof<AccountEvents>) UnionCaseInfo 不提供有关案例类型的任何信息(仅声明类型) AccountEvents


    https://stackoverflow.com/a/56351231/4636721

    let getUnionCasesTypes<'T> =
        Reflection.FSharpType.GetUnionCases(typeof<'T>)
        |> Seq.map (fun x -> x.GetFields().[0].DeclaringType)
    
    0 回复  |  直到 5 年前
        1
  •  5
  •   glennsl Namudon'tdie    5 年前

    UnionCaseInfo 有一个 GetFields 方法,该方法返回 PropertyInfo 描述联合案例的每个字段/参数的。例如:

    FSharpType.GetUnionCases(typeof<AccountEvents>)
        |> Array.map(fun c -> (c.Name, c.GetFields()))
        |> printfn "%A"
    

    将打印

    [|("AccountCreated", [|AccountCreatedArgs Item|]);
      ("AccountCredited", [|Transaction Item|]);
      ("AccountDebited", [|Transaction Item|])|]
    

    PropertyType 性质 ,因此:

    FSharpType.GetUnionCases(typeof<AccountEvents>)
        |> Array.map(fun c -> (c.Name, c.GetFields() |> Array.map(fun p -> p.PropertyType.Name)))
        |> printfn "%A"
    

    将因此打印

    [|("AccountCreated", [|"AccountCreatedArgs"|]);
      ("AccountCredited", [|"Transaction"|]);
      ("AccountDebited", [|"Transaction"|])|]