ぼっちブログ

個人ゲーム開発者やっています。主に購入したUniyアセットの使用感を書いていきます。

【C#】Enum型の名前の一覧や値の一覧、要素数をキャッシュして利用する

Enum型の値の一覧とか要素数とかが欲しい時に、GetNamesとかGetValuesを毎回書くのは無駄があるしダサいなと思ったので、値をキャッシュして利用する方法を試してみます。

バージョン情報

  • Unity 2018.3.0b12

ジェネリックの静的フィールドを使ってキャッシュする

以下のサイトを参考に、ジェネリックの静的フィールドは同じ型では共有されることを利用します。(このテクってなんか名称ありそうな気がするけど、ないのかな)

neue cc - ジェネリッククラス内の静的フィールドの挙動について

以下のようなクラスを作っておきます。

Enum制約を使っているので、要C#7.3でUnity2018.2以下だとエラー出るかも。)

using System;
using System.Collections.ObjectModel;

public static class EnumCache<T> where T : Enum
{
    public static readonly ReadOnlyCollection<string> Names = Array.AsReadOnly(Enum.GetNames(typeof(T)));
    public static readonly ReadOnlyCollection<T> Values = Array.AsReadOnly((T[])Enum.GetValues(typeof(T)));
    public static readonly int Length = Enum.GetNames(typeof(T)).Length;
}

あとはこのクラスにEnumの型を指定して呼び出すだけです。

using System.Linq;
using UnityEngine;

public class NewBehaviourScript : MonoBehaviour
{
    private enum Direction
    {
        North,
        East,
        South,
        West,
    } 

    private enum Hoge
    {
        A = 13,
        B = -10,
        C = 255,
    }

    private void Start()
    {
        Debug.Log(string.Join(",", EnumCache<Direction>.Names));
        Debug.Log(string.Join(",", EnumCache<Direction>.Values.Cast<int>()));
        Debug.Log(EnumCache<Direction>.Length);
        Debug.Log(string.Join(",", EnumCache<Hoge>.Names));
        Debug.Log(string.Join(",", EnumCache<Hoge>.Values.Cast<int>()));
        Debug.Log(EnumCache<Hoge>.Length);
    }
}

キャッシュしたEnum型の名前一覧や値一覧、要素数を表示

キャッシュされた値を利用するので、Enum.GetNamesとかEnum.GetValuesをするよりはいいんじゃないかな。