2013-09-20 4 views
19

Я использую атрибут Description в своих перечислениях для предоставления удобного имени в поле перечисления. напримерSystem.ComponentModel.DescriptionAttribute в портативной библиотеке классов

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

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

Благодаря

+1

, насколько я знаю, 'System.ComponentModel.DescriptionAttribute' фактически является частью системы' .dll', который действительно должен быть ссылкой на ваш проект. Вы не просто пропустили директиву 'using'? – olydis

+0

нет. У меня есть использование в (экземпляр вставляемого класса из предыдущей dll). Вы правы, system.componentmodel есть, просто невозможно использовать описание – Crudler

ответ

24

Поскольку 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; 
    } 
+0

звучит как хорошее решение.то в моем методе tr вывести его, просто замените DescriptionAttribute на DisplayAttribute? – Crudler

+0

@Crudler yep, я предоставил измененный код в своем ответе – Jehof

+0

приятный! thansk! – Crudler

14

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

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

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

+0

, не использующий ваше решение, но мне все равно нравится его + 1'-это :) – Crudler

3

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

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>(); 
    } 
} 

Update: также вы должны объявить новый атрибут (выглядеть 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); 
} 
+0

Вопрос в том, как объявить атрибут в PCL –

+0

обновил мой ответ –

Смежные вопросы