BEACHSIDE BLOG

Azure と GitHub と C# が好きなエンジニアの個人メモ ( ・ㅂ・)و ̑̑

enum に任意の文字列を割り当てる (C#)

過去に何度もやってると思うけど調べる機会があったので自分でメモしておこうと思います。

ここではパフォーマンスを気にしないケース (ざっくりなイメージですが 1000 回実行で 3~7 ミリ秒くらいが許容されるくらい) を想定しています。一般的なエンタープライズ系のアプリなら問題ないと思いますが、ゲームとかでハイパフォーマンスが必要なときは別の手段を使いましょう。

Attribute を使った文字列の変換のサンプルをメモしておきます。

実装サンプル

例えばこんな enum があったとして。

public enum Pets
{
    Dog,
    Cat,
    Otters,
    Rabbit
}

ここに DisplayAttribute (System.ComponentModel.DataAnnotations namespace) を使って Name を定義してそれを出力できるようにします。

public enum Pets
{
    [Display(Name = "いぬ")]
    Dog,
    [Display(Name = "にゃん")]
    Cat,
    [Display(Name = "かわうそ")]
    Otters,
    [Display(Name = "ぴょんぴょん")]
    Rabbit
}

ちなみに DisplayAttribute を使わなくても他の Attribute を使ったり、自作の Attribute を作ってもよいかと思いますがカスタムするほどでもないかなと。

あえて DisplayAttribute を使う理由があるとしたら、表示するための色々な機能が組み込まれているので、他のユースケースがあったときにさくっと使える点でしょうか。それ以上のユースケースがあれば必要に応じて自作の Attribute を作ればいいかなくらいに思ってます。

docs.microsoft.com

あとは拡張メソッドで DisplayAttribute をとれるようにします。ここでは DisplayAttribute がついてない場合、enum の文字列をそのまま返すようにしてますが、 DisplayAttribute が無い場合に例外をはくとか null を返すとかはユースケース次第でしょう。

public static class PetsExtensions
{
    public static string ToDisplayName(this Pets source)
    {
        string internalFormat = source.ToString();
        var displayAttribute = source.GetType().GetField(internalFormat)?.GetCustomAttribute<DisplayAttribute>();
        return displayAttribute?.Name ?? internalFormat;
    }
}

使うときはこんな感じですね。

// ぴょんぴょん
var rabbitDisplayName = Pets.Rabbit.ToDisplayName();

参考

docs.microsoft.com

GetCustomAttribute(ParameterInfo)