3

I have two enums, one with flags and another without:

[Flags]
public enum MyEnumWithFlags {
  [Description("Item 1")] 
  Item1 = 1,
  [Description("Item 2")] 
  Item2 = 2,
  [Description("Item 3")] 
  Item3 = 4,
}

public enum MyEnum {
  [Description("Item 1")] 
  Item1,
  [Description("Item 2")] 
  Item2,
  [Description("Item 3")] 
  Item3,
}

To get the attributes I tried:

  var a = MyEnumWithFlags.Item1 | MyEnumWithFlags.Item3;

  var b = a.GetAttributes<DescriptionAttribute>();

This works fine. Variable b has to attributes: "Item 1" and "Item 2".

Then I tried with Myenum that has no flags:

  var c = MyEnum.Item1;

  var d = c.GetAttributes<DescriptionAttribute>();

In this case variable d has all the enum attributes. Not only the Item1.

Does anyone knows what might be wrong? The GetAttributes extension is:

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;

} 

UPDATE

By checking if the enum is of type flags I end up with the following:

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

  Type type = value.GetType();

  if (type.GetCustomAttributes<FlagsAttribute>().Any()) {

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

    IEnumerable<Enum> flags = Enum.GetValues(type).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;

    }

  } else {

    MemberInfo info = type.GetMember(value.ToString()).FirstOrDefault();

    if (info != null)
      return new List<T> { (T)info.GetCustomAttributes(typeof(T), false).FirstOrDefault() };

  }

  return null;

} // GetAttributes  

It seems to work now with Flags Enums and No Flags Enums.

Does anyone thinks that this code could be improved?

Thank You

Miguel Moura
  • 36,732
  • 85
  • 259
  • 481
  • 1
    Your code works. Just use correct extension method name `c.Attributes();` – Sergey Berezovskiy Feb 20 '14 at 14:24
  • This has to be a duplicate. I know I have seen this question before. – John Alexiou Feb 20 '14 at 14:36
  • The extension name was a typo ... It does not work when the enum has no flags – Miguel Moura Feb 20 '14 at 14:51
  • Not really a duplicate ... I do not want to get all attributes of all items of the enum ... I want to get the attributes of the items of the variable which has that enum type. The values I get in b are ok but in d are not. Could someone please try my code? You will see what I am talking about ... – Miguel Moura Feb 20 '14 at 15:00
  • In "b" I get two attributes as expected and in "d" I get 3 attributes when I should get 1 ... Do you understand? – Miguel Moura Feb 20 '14 at 15:01
  • I am not sure if I need to distinguish enums that has flags and others that have not – Miguel Moura Feb 20 '14 at 15:02
  • 1
    Check out the docs for `HasFlag`. It says it's only intended for Enums marked with the Flag Attribute. http://msdn.microsoft.com/en-us/library/system.enum.hasflag(v=vs.110).aspx – juharr Feb 20 '14 at 15:04
  • Do you know a way to find if the enum has flags? I would like the extension to work in all situations. Does it make sense? – Miguel Moura Feb 20 '14 at 15:06
  • 1
    @MDMoura Check this out for determining if the `Enum` is marked with the Flag attribute. http://stackoverflow.com/questions/14461460/finding-out-if-an-enum-has-the-flags-attribute-set – juharr Feb 20 '14 at 15:08
  • Just solved the problem with your info and updated my code. If anyone has a suggestion to improve it just let me know. – Miguel Moura Feb 20 '14 at 15:22
  • 1
    A minor suggestion - store the value of `value.GetType()` in a variable - reflection methods are pretty expensive. – Stephan Zaria Feb 20 '14 at 15:30
  • Just updated the code to contemplate your value.GetType() suggestion – Miguel Moura Feb 20 '14 at 15:34

0 Answers0