web-dev-qa-db-ja.com

ポータブルクラスライブラリのSystem.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,
}

そして、これにアクセスするのは、Niceヘルパーメソッドを使用すると簡単です。

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は私がすでにすべてを参照していることを教えてくれます。

ありがとう

24
Crudler

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

ポータブルクラスライブラリで何かを利用できるかどうかは、ライブラリ用に選択したフレームワークに少し依存します。厳密な共通部分のみが得られます。ただし、この属性が対象のフレームワークの1つに存在しない可能性があります。その場合、1つのオプションは独自に追加-次にあなた知っているそれが利用可能です。例えば:

[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に変更するのはかなり簡単なはずです。

16
Marc Gravell

ポータブルライブラリで列挙型の属性を取得するには、これを試してください。

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クラスにもう1つのメソッドを追加します。

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);
}
3
Bogdan Kanteruk