I have a problem I have a simple enum with description attribute in c#
public enum Service
{
[Description("Unknown")]
Unknown = 0
}
No I have extension in f# that will get me that description and it looks like:
[<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:
[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 :
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)'. There is no boxing conversion from 'Enums.Service' to '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. 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
. 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:
[<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#:
string result = Service.Unknown.GetEnumDescription();
Console.WriteLine(result);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.