Miguel Moura
Miguel Moura

Reputation: 39354

Enum Description to String

I have the following ENUM:

[Flags]
public enum DataFiat {

  [Description("Público")]
  Public = 1,

  [Description("Filiado")]
  Listed = 2,

  [Description("Cliente")]
  Client = 4

} // DataFiat

And I created an extension to get an Enum attribute:

public static T GetAttribute<T>(this Enum value) where T : Attribute {

  T attribute;
  MemberInfo info = value.GetType().GetMember(value.ToString()).FirstOrDefault();
  if (info != null) {
    attribute = (T)info.GetCustomAttributes(typeof(T), false).FirstOrDefault();
    return attribute;
  }
  return null;
}

This works for non Flags Enums ... But when I have:

var x = DataFiat.Public | DataFiat.Listed;
var y = x.GetAttribute<Description>();

The value of y is null ...

I would like to get "Público, Filiado, Cliente" ... Just as ToString() works.

How can I change my extension to make this work?

Thank You

Upvotes: 8

Views: 6108

Answers (5)

John Smith
John Smith

Reputation: 153

in .NET CORE without any additional libraries you can do:

 public enum Divisions
 {
    [Display(Name = "My Title 1")]
    None,
    [Display(Name = "My Title 2")]
    First,
 }

and to get the title:

using System.ComponentModel.DataAnnotations
using System.Reflection

string title = enumValue.GetType()?.GetMember(enumValue.ToString())?[0]?.GetCustomAttribute<DisplayAttribute>()?.Name;

Upvotes: 1

Miguel Moura
Miguel Moura

Reputation: 39354

I came up with a different solution based on my previous code. It can be used as follows:

  DataFiat fiat = DataFiat.Public | DataFiat.Listed;
  var b = fiat.ToString();
  var c = fiat.GetAttributes<TextAttribute>();

  var d = fiat.GetAttributes<TextAttribute, String>(x => String.Join(",", x.Select(y => y.Value)));

I think it becomes easy to use either to get the attributes or doing something with them.

What do you think?

Let me know if the code can be somehow improved. Here is the code:

public static List<T> GetAttributes<T>(this Enum value) where T : Attribute {

  List<T> attributes = new List<T>();

  IEnumerable<Enum> flags = Enum.GetValues(value.GetType()).Cast<Enum>().Where(value.HasFlag);

  if (flags != null) {

    foreach (Enum flag in flags) {
      MemberInfo info = flag.GetType().GetMember(flag.ToString()).FirstOrDefault();
      if (info != null)
        attributes.Add((T)info.GetCustomAttributes(typeof(T), false).FirstOrDefault());         
    }

    return attributes;

  }

  return null;

} // GetAttributes   

public static Expected GetAttributes<T, Expected>(this Enum value, Func<List<T>, Expected> expression) where T : Attribute {

  List<T> attributes = value.GetAttributes<T>();

  if (attributes == null)
    return default(Expected);

  return expression(attributes);

} // GetAttributes 

Upvotes: -1

Bassam Alugili
Bassam Alugili

Reputation: 16983

using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;

public static class Program
{
[Flags]
public enum DataFiat
{

  [Description("Público")]
  Public = 1,

  [Description("Filiado")]
  Listed = 2,

  [Description("Cliente")]
  Client = 4

} 

public static ICollection<string> GetAttribute<T>(this Enum value)
{
  var result = new Collection<string>();
  var type = typeof(DataFiat);

  foreach (var value1 in Enum.GetValues(type))
  {
    var memInfo = type.GetMember(value1.ToString());
    var attributes = memInfo[0].GetCustomAttributes(typeof(DescriptionAttribute), false);
    var description = ((DescriptionAttribute)attributes[0]).Description;
    result.Add(description);
  }

  return result;
}

static void Main(string[] args)
{
  var x = DataFiat.Public | DataFiat.Listed;
  var y = x.GetAttribute<DataFiat>();

  var output = string.Join(" ", y.ToArray());
  Console.WriteLine(output);
}
}

I have changed the T to ICollection but you can change it as you wish or you can merege the data within the method and return the string back.

Upvotes: 0

Serginho
Serginho

Reputation: 7490

I think you want to make something like that

using System;

public enum ArrivalStatus { Unknown=-3, Late=-1, OnTime=0, Early=1 };

public class Example
{
   public static void Main()
   {
      int[] values = { -3, -1, 0, 1, 5, Int32.MaxValue };
      foreach (var value in values)
      {
         ArrivalStatus status;
         if (Enum.IsDefined(typeof(ArrivalStatus), value))
            status = (ArrivalStatus) value;
         else
            status = ArrivalStatus.Unknown;
         Console.WriteLine("Converted {0:N0} to {1}", value, status);
      }
   }
}
// The example displays the following output:
//       Converted -3 to Unknown
//       Converted -1 to Late
//       Converted 0 to OnTime
//       Converted 1 to Early
//       Converted 5 to Unknown
//       Converted 2,147,483,647 to Unknown

Upvotes: 0

Patrick Hofman
Patrick Hofman

Reputation: 156918

You can use this:

var values = x.ToString()
             .Split(new[] { ", " }, StringSplitOptions.None)
             .Select(v => (DataFiat)Enum.Parse(typeof(DataFiat), v));

To get the individual values. Then get the attribute values of them.

Something like this:

var y2 = values.GetAttributes<DescriptionAttribute, DataFiat>();

public static T[] GetAttributes<T, T2>(this IEnumerable<T2> values) where T : Attribute
{
    List<T> ts =new List<T>();

    foreach (T2 value in values)
    {
        T attribute;
        MemberInfo info = value.GetType().GetMember(value.ToString()).FirstOrDefault();
        if (info != null)
        {
            attribute = (T)info.GetCustomAttributes(typeof(T), false).FirstOrDefault();
            ts.Add(attribute);
        }
    }

    return ts.ToArray();
}

Upvotes: 2

Related Questions