(C#)Enumからstringへの変換
よくあるEnumからstringへの変換。世の中に大量に公開されている正解をツギハギして自分にちょうどいいものを探ってみた。
属性定義と拡張メソッドが必要だった。属性定義はDisplayNameAttributeがEnumメンバに付与できないので必要で、拡張メソッドは簡単にアクセスするために必要。DisplayName派生の方が無難だけど参考URL1つ目の思想も好きなので混ざっている。。
ソースコード
using System; using System.Linq; namespace EnumToString { // 独自Attribute [AttributeUsage(AttributeTargets.Field, Inherited = false, AllowMultiple = false)] public sealed class AliasNameAttribute : Attribute { public string AliasName { get; private set; } public AliasNameAttribute(string aliasName) { AliasName = aliasName; } } // 独自Attribute用のEnum拡張 public static partial class EnumExtension { // どうしてもメソッドチェインを崩したくない人用 public static T ThrowIf<T>(this T value, Func<T, bool> predicate, Exception exception) { if (predicate(value)) throw exception; else return value; } // AliasNameAttribute.AliasNameを返す。定義されていなければ例外を発生させる。 public static string ToAliasName(this Enum value) { return value.GetType() .GetField(value.ToString()) .GetCustomAttributes(typeof(AliasNameAttribute), false) .Cast<AliasNameAttribute>() .FirstOrDefault() .ThrowIf(a => a == null, new ArgumentException("属性が設定されていません。")) .AliasName; } } // DisplayName継承Attribute // System.ComponentModel.DisplayNameAttributeと衝突する(こちらへ置換可能) [AttributeUsage(AttributeTargets.All, AllowMultiple = false)] public class DisplayNameAttribute : System.ComponentModel.DisplayNameAttribute { public DisplayNameAttribute(string displayName) : base(displayName) { } } // DisplayName継承Attribute用のEnum拡張 public static partial class EnumExtension { // DisplayNameAttribute.DisplayNameを返す。定義されていなければ定義名を返す。 public static string ToDisplayName(this Enum value) { var attribute = value.GetType() .GetField(value.ToString()) .GetCustomAttributes(typeof(DisplayNameAttribute), false) .Cast<DisplayNameAttribute>() .FirstOrDefault(); return (attribute != null) ? attribute.DisplayName : value.ToString(); } } // enum enum Fruit { [AliasName("ブドウ")] Grape, [DisplayName("あっぷる")] [AliasName("リンゴ")] Apple, [DisplayName("おれんじ")] [AliasName("オレンジ")] Orange, // 属性なし Dummy, } class Program { static void Main(string[] args) { // AliasName属性を使用して全要素を表示 foreach (Fruit f in Enum.GetValues(typeof(Fruit))) { try { Console.WriteLine(f.ToString()); Console.WriteLine($" {f.ToAliasName()}"); } catch (Exception e) { Console.WriteLine($" exception : {e.ToString()}"); } } Console.WriteLine(); // DisplayName属性を使用して全要素を表示 Console.WriteLine("================"); foreach (Fruit f in Enum.GetValues(typeof(Fruit))) { try { Console.WriteLine(f.ToString()); Console.WriteLine($" {f.ToDisplayName()}"); } catch (Exception e) { Console.WriteLine($" exception : {e.ToString()}"); } } Console.WriteLine(); // wait for key Console.ReadKey(); } } }
結果
Grape ブドウ Apple リンゴ Orange オレンジ Dummy exception : System.ArgumentException: 属性が設定されていません。 場所 EnumToString.EnumExtension.ThrowIf[T](T value, Func`2 predicate, Exception exception) 場所 ***\Program.cs:行 64 場所 EnumToString.EnumExtension.ToAliasName(Enum value) 場所 ***\Program.cs:行 71 場所 EnumToString.Program.Main(String[] args) 場所 ***\Program.cs:行 107 ================ Grape Grape Apple あっぷる Orange おれんじ Dummy Dummy