使用f#扩展名从c#中的枚举获取枚举描述属性

时间:2019-07-05 11:28:28

标签: c# enums f#

我有一个问题,我在C#中有一个带有description属性的简单枚举

public enum Service 
{
    [Description("Unknown")]
    Unknown = 0
}

不,我在f#中有扩展名,该扩展名将使我得到该描述,它看起来像:

[<Extension>]
static member inline GetEnumDescription(enum:'TEnum when 'TEnum :> Enum) : string =      

    try
        let attributes : seq<DescriptionAttribute[]> = enum.GetType().GetField(enum.ToString()).GetCustomAttributes(typedefof<DescriptionAttribute>, false) |> Seq.cast<DescriptionAttribute[]>             

        match attributes |> Seq.length > 0 with
            | true -> 
                let attribute : DescriptionAttribute = enum |> Seq.head
                attribute.Description
            | _ -> enum.ToString()
    with 
        | :? EnumException as ex -> 
            EnumExtensions._logger.Error(sprintf "Exception in getting enum description - %s" ex.Message)
            enum.ToString()

所以c#中的meta看起来像:

 [CompilationMapping(SourceConstructFlags.ObjectType)]
public class EnumExtensions
{
    public EnumExtensions();

    public static string GetEnumDescription<TEnum>(this TEnum @enum) where TEnum : Enum, IEnumerable<DescriptionAttribute>;
}

现在,当我尝试在c#调用中使用它时:

public string Description => Service.GetEnumDescription(); //Service is set to Unknown enum value

我得到类似的东西:

  

错误CS0315类型'Enums.Service'不能用作通用类型或方法'EnumExtensions.GetEnumDescription(TEnum)'中的类型参数'TEnum'。没有从“ Enums.Service”到“ System.Collections.Generic.IEnumerable”的装箱转换。

我为此感到迷茫。

2 个答案:

答案 0 :(得分:1)

据我所知,这里:

let attribute : DescriptionAttribute = enum |> Seq.head

您将enum当作一个序列对待,试图提取其头部。这导致F#期望enum为序列类型,因此发出的C#元数据对IEnumerable<DescriptionAttribute>具有TEnum约束。我想这行应该是

let attribute : DescriptionAttribute = attributes |> Seq.head

答案 1 :(得分:1)

我也无法使其正常工作,但是您可以将F#方法重写为:

[<Extension>]
type Extensions =
    [<Extension>]
    static member inline GetEnumDescription(enum:'TEnum when 'TEnum :> Enum) : string =      

        let attributes = enum.GetType().GetField(enum.ToString()).GetCustomAttributes(typeof<DescriptionAttribute>, false)
        match attributes.Length with
        | x when x > 0 -> attributes.[0] |> (fun a -> a :?> DescriptionAttribute) |> fun a -> a.Description
        | _ -> raise (InvalidOperationException("DescriptionAttribute is missing"))

从C#调用时,您将从DescriptionAttributes获取Description属性:

  string result = Service.Unknown.GetEnumDescription();
  Console.WriteLine(result);