Hank
Hank

Reputation: 2616

How to get a custom attribute on enum by passing in the enum value and attribute type?

there are lots of examples online of creating a enum extension method that takes a enum value as an argument and in the method gets a specific attribute, like so:

namespace MVVMProj.ProjUtilities
{
  public class EnumerationHelpers
  {
    public static string GetStatusText(this Enum value)
    {
      var type = value.GetType();

      string name = Enum.GetName(type, value);
      if (name == null) { return null; }

      var field = type.GetField(name);
      if (field == null) { return null; }

      var attr = Attribute.GetCustomAttribute(field, typeof(StatusTextAttribute)) as StatusTextAttribute;
      if (attr == null) { return null; }

      return attr.StatusText;
    }
  }
}

What I'm wondering is, is there a way to also pass the method the attribute type, so I don't need to keep writing specific methods for each different attribute?

This is unfinished, but, it should give you the idea of what I'm trying to achieve:

namespace MVVMProj.ProjUtilities
{
  public class EnumerationHelpers
  {
    public static string GetCustomAttribute(this Enum value, Type customAttr) 
             //Or instead of passing a Type, a string of the attribute's name
    {
      var type = value.GetType();

      string name = Enum.GetName(type, value);
      if (name == null) { return null; }

      var field = type.GetField(name);
      if (field == null) { return null; }

      var attr = Attribute.GetCustomAttribute(field, ....) as ....;
      if (attr == null) { return null; }

      return attr....;
    }
  }
}

I suppose I can't just return a string either as it could be any data type.

Some generic method maybe?

Any advice would be greatly appreciated!

Edit: Usage:

It is iterating over the enum creating a dictionary so I can display the values in a combobox. It only adds the item if the attribute matches the condition in the if statement.

One more thing to note is that the custom attribute is an enum as well.

Aybe: the 'item' is only an object upon the iteration so I do a cast. Though I am getting an error in the if statement, it trying to compare CaseTypeAttribute to an actual CaseType enum value, what do I need to do to resolve?

Error:
Severity Code Description Project File Line Suppression State Error CS0019 Operator '==' cannot be applied to operands of type 'SBC.CaseTypeAttribute' and 'SBC.CaseType'

private Dictionary<int, string> _substancetypes;
public Dictionary<int, string> SubstanceTypes
{
  get
  {
    if (_substancetypes == null)
    {
      _substancetypes = new Dictionary<int, string>();
      foreach (var item in Enum.GetValues(typeof(SBC.SubstanceTypeCode)))
      {
        var descriptionAttribute = ((SBC.SubstanceTypeCode)item).GetAttribute<SBC.CaseTypeAttribute>();
        if (descriptionAttribute != null && 
               descriptionAttribute == SBC.CaseType.Exposures) //Error here
        {
          _substancetypes.Add((int)item, CTS_MVVM.CTS_Utilities.EnumerationHelpers.GetDescriptionFromEnumValue((SBC.SubstanceTypeCode)item));
        }
      }
    }

    return _substancetypes;
  }
}

Upvotes: 1

Views: 2623

Answers (1)

aybe
aybe

Reputation: 16652

Something like this?

using System;
using System.ComponentModel;
using System.Reflection;

namespace ConsoleApp1
{
    internal static class Program
    {
        private static void Main(string[] args)
        {
            var descriptionAttribute = MyEnum.A.GetAttribute<DescriptionAttribute>();
        }
    }

    public static class EnumExtensions
    {
        public static T GetAttribute<T>(this Enum @enum) where T : Attribute
        {
            var type = @enum.GetType();
            var name = Enum.GetName(type, @enum);
            var field = type.GetField(name);
            var attribute = field.GetCustomAttribute<T>();
            return attribute;
        }
    }

    public enum MyEnum
    {
        [Description("A")] A,
        [Description("B")] B
    }
}

Upvotes: 2

Related Questions