Как получить пользовательский атрибут в enum, передав значение enum и тип атрибута? - PullRequest
1 голос
/ 07 апреля 2020

В Интернете есть множество примеров создания метода расширения перечисления, который принимает значение перечисления в качестве аргумента и в методе получает указанный атрибут c, например:

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 ' Интересно, есть ли способ также передать метод тип атрибута, поэтому мне не нужно продолжать писать конкретные c методы для каждого отдельного атрибута?

Это незакончено, но оно должно дать вам представление о том, чего я пытаюсь достичь:

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....;
    }
  }
}

Полагаю, я не могу просто вернуть строку, так как это может быть любой тип данных.

Some generi c Метод может быть?

Любой совет будет принята с благодарностью!

Редактировать: Использование:

Он перебирает перечисление, создавая словарь так Я могу отобразить значения в выпадающем списке. Он добавляет элемент только в том случае, если атрибут соответствует условию в операторе if.

Еще одна вещь, на которую следует обратить внимание: пользовательский атрибут также является перечислением.

Aybe: 'item' только объект на итерации, поэтому я выполняю приведение. Хотя я получаю сообщение об ошибке в операторе if, он пытается сравнить CaseTypeAttribute с фактическим значением перечисления CaseType, что мне нужно сделать, чтобы устранить?

Ошибка: Код серьезности Описание Ошибка состояния подавления строки файла проекта CS0019 Оператор '==' не может применяться к операндам типа 'SB C .CaseTypeAttribute' и 'SB C .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;
  }
}

1 Ответ

2 голосов
/ 07 апреля 2020

Как то так?

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
    }
}
...