8

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

Jonathan Nixon
  • 4,940
  • 5
  • 39
  • 53
Miguel Moura
  • 36,732
  • 85
  • 259
  • 481
  • 3
    [Break the flags down into the individual values](http://stackoverflow.com/questions/4171140/iterate-over-values-in-flags-enum), get the attribute for each individual value and build up a string of them all. – Adam Houldsworth Feb 19 '14 at 14:34
  • But it wouldn't work here since your extension method returns only 1 value, however what you want to do is to return a list of values. Otherwise the extension method would need to have the knowledge how to combine those attributes – peter Feb 19 '14 at 14:35
  • 1
    This is not going to localise very nicely if you will want english speakers to use it. – Gusdor Feb 19 '14 at 14:40

5 Answers5

2

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();
}
Community
  • 1
  • 1
Patrick Hofman
  • 153,850
  • 22
  • 249
  • 325
1

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;
TheAccessMan
  • 133
  • 10
0

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
Serginho
  • 7,291
  • 2
  • 27
  • 52
0
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.

Bassam Alugili
  • 16,345
  • 7
  • 52
  • 70
-1

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 
admdrew
  • 3,790
  • 4
  • 27
  • 39
Miguel Moura
  • 36,732
  • 85
  • 259
  • 481