列挙体と日本語の問題
列挙体(Enum)を定数とて定義する場合などに問題となるのが日本語の問題。C#のコードはUTF-8なので日本語で書けないことないけど、
通常は列挙体や列挙子は英語もしくはローマ字表記となる。
こうした定義に対しView(UI)やログなどで必要となるのは対応する日本語であったりする。
列挙体とは別個に定義でもよいが属性を使うともう少しマシな実装が可能となる。
属性
属性とはクラスやそのメンバなどに付与するメタ情報のこと例えばSystem.ObsoleteAttributeという属性は、互換性のために残してあるが使用が推奨されないことをVisualStudioを介して明示するためのものである。
[Obsolete("次期のリリースで削除予定")]
public void Sample(){};
属性の実装
属性は以下のように定義することで独自実装も可能- System.Attributeクラスを継承する
- HogeHogeAttributeのように接尾辞にAttributeを付与する
- System.AttributeUsageAttributeで適応対象を指定する
[AttributeUsage(AttributeTargets.Enum | AttributeTargets.Field)] // 適用対象指定
public class AliasAttribute : Attribute // Attributeを継承
{
private string _text; // バックストア
public string Text => _text; // 文字列取得用プロパティ
public AliasAttribute(string text) { _text = text; } // 文字列を1つとるコンストラクタ
}
属性による日本語の定義
上記で定義した属性を用いて列挙体に日本語定義を付加した記述例
[Alias("四国地方")]
enum ShikokuPrefecture
{
[Alias("愛媛県")]
Ehime,
[Alias("香川県")]
Kagawa,
[Alias("高知県")]
Kouchi,
[Alias("徳島県")]
Tokushima
}
属性として定義された文字列の取得
属性や属性の値はリフレクションにより取得する。以下は拡張メソッドとしてAlias属性が付与されている場合はその値を、無い場合はNullを返すコード例
using System.Reflection; // これも必要
public static class EnumExtensions
{
// 列挙値に付与されている別名の取得
public static string ToAliasString(this Enum target)
{
var attribute = target.GetType().GetMember(target.ToString())[0].GetCustomAttribute(typeof(AliasAttribute));
return attribute == null ? null : ((AliasAttribute)attribute).Text;
}
// 列挙体に付与されている別名の取得
public static string ToAliasEnumString(this Enum target)
{
Attribute attribute = target.GetType().GetCustomAttribute(typeof(AliasAttribute));
return attribute == null ? null : ((AliasAttribute)attribute).Text;
}
}
上記の拡張メソッドを用いたコード例
ShikokuPrefecture sk = ShikokuPrefecture.Ehime;
string test1 = sk.ToString(); // 実行結果:Ehime
string test2 = sk.ToAliasString(); // 実行結果:愛媛県
string test3 = sk.ToAliasEnumString(); // 実行結果:四国地方