Получить атрибут описания enum из enum в c #, используя расширение f # - PullRequest
3 голосов
/ 05 июля 2019

У меня проблема У меня есть простое перечисление с атрибутом description в c #

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 # выглядит так:

 [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' нельзя использовать в качестве параметра типа 'TEnum' в универсальном типе или методе 'EnumExtensions.GetEnumDescription (TEnum)'. Преобразование из «Enums.Service» в «System.Collections.Generic.IEnumerable» отсутствует.

Я потерян в этом.

Ответы [ 2 ]

1 голос
/ 05 июля 2019

Я тоже не могу заставить его работать, но вы можете переписать метод 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"))

После этого вы получите свойство Description из DescriptionAttributes при вызове из C #:

  string result = Service.Unknown.GetEnumDescription();
  Console.WriteLine(result);
1 голос
/ 05 июля 2019

Насколько я вижу, здесь:

let attribute : DescriptionAttribute = enum |> Seq.head

вы рассматриваете enum как последовательность, пытаясь извлечь ее голову.Это приводит к тому, что F # ожидает, что enum будет иметь тип последовательности, и, таким образом, выдаваемая мета C # имеет ограничение IEnumerable<DescriptionAttribute> для TEnum.Я думаю, что строка должна быть

let attribute : DescriptionAttribute = attributes |> Seq.head
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...