简体   繁体   English

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

[英]Get enum description attribute from enum in c# using f# extension

I have a problem I have a simple enum with description attribute in c# 我有一个问题我在c#中有一个带有描述属性的简单枚举

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

No I have extension in f# that will get me that description and it looks like: 不,我在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()

So meta in c# looks like: 所以c#中的meta看起来像:

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

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

Now when i try using this in c# calling : 现在当我尝试在c#调用中使用它时:

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

I am getting something like: 我得到的东西是这样的:

Error CS0315 The type 'Enums.Service' cannot be used as type parameter 'TEnum' in the generic type or method 'EnumExtensions.GetEnumDescription(TEnum)'. 错误CS0315类型'Enums.Service'不能在泛型类型或方法'EnumExtensions.GetEnumDescription(TEnum)'中用作类型参数'TEnum'。 There is no boxing conversion from 'Enums.Service' to 'System.Collections.Generic.IEnumerable'. 没有从'Enums.Service'到'System.Collections.Generic.IEnumerable'的装箱转换。

I am lost at this. 我迷失了。

As far as I can see, here: 据我所知,这里:

let attribute : DescriptionAttribute = enum |> Seq.head

you're treating enum like a sequence, trying to extract its head. 你把enum当作一个序列来对待,试图提取它的头部。 That causes F# to expect enum to be of a sequence type, and thus the emitted C# meta has the IEnumerable<DescriptionAttribute> constraint on TEnum . 这导致F#期望enum为序列类型,因此发出的C#meta在TEnum上具有IEnumerable<DescriptionAttribute>约束。 I guess the line should be 我猜这行应该是

let attribute : DescriptionAttribute = attributes |> Seq.head

I can't get it to work either, but you can rewrite the F# method to: 我也无法让它工作,但你可以重写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"))

You'll then get the Description property from the DescriptionAttributes when calling from C#: 然后你会得到从Description属性DescriptionAttributes从C#调用时:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM