24

我在枚举中使用 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;
    }

我需要将其转换为可移植类库,但它似乎无法访问 System.ComponentModel 库。当我尝试添加崇敬时,VS 告诉我我已经引用了所有内容。

谢谢

4

3 回答 3

28

由于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;
    }
于 2013-09-20T09:15:25.187 回答
16

可移植类库是否可以使用某些东西在某种程度上取决于您为该库选择了哪些框架——您只会得到严格的交集。但是,很可能此属性根本不存在于您的目标框架之一中。在这种情况下,一个选项是添加您自己的- 然后您知道它是可用的。例如:

[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[EnumDescription]/EnumDescriptionAttribute应该相当简单。

于 2013-09-20T09:15:27.020 回答
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>();
    }
}

更新:您还应该声明新属性(看起来像 PCL 中不可用的 DescriptionAttribute),例如下一个:

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);
}
于 2014-05-28T08:22:17.970 回答