Система.ComponentModel.DescriptionAttribute в переносимой библиотеке классов

Я использую атрибут Description в моих перечислениях, чтобы предоставить удобное имя для поля перечисления. например,

public enum InstallationType
{
    [Description("Forward of Bulk Head")]
    FORWARD = 0,

    [Description("Rear of Bulk Head")]
    REAR = 1,

    [Description("Roof Mounted")]
    ROOF = 2,
}

и доступ к этому легко с хорошим вспомогательным методом:

public static string GetDescriptionFromEnumValue(Enum value)
    {
        DescriptionAttribute attribute = value.GetType()
            .GetField(value.ToString())
            .GetCustomAttributes(typeof(DescriptionAttribute), false)
            .SingleOrDefault() as DescriptionAttribute;
        return attribute == null ? value.ToString() : attribute.Description;
    }

мне нужно преобразовать это в портативную библиотеку классов, но, похоже, у нее нет доступа к системе.Библиотека ComponentModel. когда я пытаюсь добавить почтение, VS говорит мне, что я уже ссылался на все.

спасибо

3 ответов


С DescriptionAttribute недоступно для переносимых библиотек классов, вам нужно использовать другой атрибут. Пространство имен System.ComponentModel.DataAnnotations который доступен для переносимых библиотек классов, предоставляет атрибут DisplayAttribute что вы можете использовать вместо этого.

public enum InstallationType
{
    [Display(Description="Forward of Bulk Head")]
    FORWARD = 0,

    [Display(Description="Rear of Bulk Head")]
    REAR = 1,

    [Display(Description="Roof Mounted")]
    ROOF = 2,
}

ваш метод должен быть изменен на

public static string GetDescriptionFromEnumValue(Enum value)
    {
        DisplayAttribute attribute = value.GetType()
            .GetField(value.ToString())
            .GetCustomAttributes(typeof(DisplayAttribute ), false)
            .SingleOrDefault() as DisplayAttribute ;
        return attribute == null ? value.ToString() : attribute.Description;
    }

доступно ли что - то для переносимой библиотеки классов, зависит немного от того, какие именно фреймворки вы выбрали для библиотеки-вы получаете только строгое пересечение. Однако, вполне возможно, что этот атрибут просто не существует в один из ваших целевых структур. В этом случае, одним из вариантов является добавить свои собственные - тогда вы знаю это доступно. Например:

[AttributeUsage(AttributeTargets.Field, AllowMultiple = false)]
public class EnumDescriptionAttribute :Attribute
{
    private readonly string description;
    public string Description { get { return description; } }
    public EnumDescriptionAttribute(string description)
    {
        this.description = description;
    }
}

enum Foo
{
    [EnumDescription("abc")]
    A,
    [EnumDescription("def")]
    B
}

обратите внимание, что я намеренно не включены дополнительные здесь используются константы сериализации, поскольку они также зависят от функций, доступных не во всех фреймворках. Изменение кода с помощью [Description] / DescriptionAttribute to [EnumDescription] / EnumDescriptionAttribute должно быть довольно тривиальной.


попробуйте это для получения атрибута для перечисления в портативных библиотеках:

public static class EnumsHelper
{
    public static T GetAttributeOfType<T>(this Enum enumVal) where T : Attribute
    {
        var typeInfo = enumVal.GetType().GetTypeInfo();
        var v = typeInfo.DeclaredMembers.First(x => x.Name == enumVal.ToString());
        return v.GetCustomAttribute<T>();
    }
}

обновление: также вы должны объявить новый атрибут (похожий на DescriptionAttribute, недоступный в PCL), например:

public class MyDescriptionAttribute : Attribute
{
    public virtual string Text { get; set; }
}

и добавьте еще один метод в класс EnumsHelper:

public static class EnumsHelper
{
    ...

    public static string GetDescription(this Enum enumVal)
    {
        var attr = GetAttributeOfType<MyDescriptionAttribute>(enumVal);
        return attr != null ? attr.Text : string.Empty;
    }
}

и если у вас есть следующие перечисления:

public enum InstallationType
{
    [MyDescription(Text = "Forward of Bulk Head")]
    FORWARD = 0
}

вы можете получить описание с такой код:

static void Main(string[] args)
{
    var it = InstallationType.FORWARD;
    var description = it.GetDescription();
    Console.WriteLine(description);
}