ネコのために鐘は鳴る

寺院に住み着くパソコ〇好き

(C#)Enumの要素に表示名をつける ~ローカライズ編~

前回の記事の続きです

前回はEnumDisplayName属性に定数リテラル文字列を与えることはできましたが、 リソースから値を割りつけることができませんでした。これでは多言語化する時に困ります。

[AttributeUsage(AttributeTargets.Field)]
public class EnumDisplayNameAttribute : Attribute
{
    /// <summary>表示名</summary>
    public string Name { get; set; }

    /// <summary>enum表示名属性</summary>
    /// <param name="name">表示名</param>
    public EnumDisplayNameAttribute(string name)
    {
        Name = name;
    }
}
public enum Sushi
{
   [EnumDisplayName("タコ")]    // リテラルを割り付けることはできる
   Tako,
   [EnumDisplayName("イカ")]
   Ika,
   [EnumDisplayName(Resources.SushiEbi)]  // リソース値はコンパイルエラーになる
   Ebi
}

そこで以下のようにEnumDisplayNameAttributeクラスを修正します。

using System.Reflection;

[AttributeUsage(AttributeTargets.Field)]
public class EnumDisplayNameAttribute : Attribute
{
    /// <summary>表示名</summary>
    public string Name { get; set; }

    /// <summary>リソース名</summary>
    public string Resource
    {
        get { return _resource; }
        set { _resource = value; SetNameFromResource(); }
    }
    private string _resource;

    /// <summary>リソースの型</summary>
    public Type ResourceType
    {
        get { return _resourceType; }
        set { _resourceType = value; SetNameFromResource(); }
    }
    private Type _resourceType;

    /// <summary>enum表示名属性</summary>
    public EnumDisplayNameAttribute() { }

    /// <summary>enum表示名属性</summary>
    /// <param name="name">表示名</param>
    public EnumDisplayNameAttribute(string name)
    {
        Name = name;
    }

    /// <summary>リソース型とリソース名から表示名をセットします</summary>
    private void SetNameFromResource()
    {
        if(_resourceType == null || _resource == null) { return; }
        var propertyInfo = _resourceType.GetProperty(_resource);
        Name = propertyInfo?.GetValue(_resourceType) as string;
    }
}

そしてEnumに次のように属性を与えます

public enum Sushi
{
    [EnumDisplayName(Resource = "SushiTako", ResourceType = typeof(Resources))]
    Tako,
    [EnumDisplayName(Resource = "SushiIka", ResourceType = typeof(Resources))]
    Ika,
    [EnumDisplayName(Resource = "SushiEbi", ResourceType = typeof(Resources))]
    Ebi,
}

Resources.SushiEbi等がリソース値です。これで無事リソースから表示名を割り付けることができたので 多言語にローカライズできます。