LoginSignup
23
18

More than 5 years have passed since last update.

文字列テーブルから動的にenum型を作る

Posted at

案外情報が少なかった気がするのでまとめてみた。

ほとんどのことは文字列テーブルでも動的Enumでも同じことができる。

ただ、値の比較は文字列よりも動的Enumの方が早い。
(「文字列の比較」と「数値の比較」なので当たり前ですが)

値の比較を頻繁に行うような場合は動的にEnumを作成しても良いかもね。
(文字列テーブルのインデックス比較でも良いのですけどね。。。)

作り方

using System.Reflection;
using System.Reflection.Emit;

static System.Type BuildEnum(string[] strings)
{
    AssemblyName asmName = new AssemblyName{ Name = "MyAssembly" };
    System.AppDomain domain = System.AppDomain.CurrentDomain;
    AssemblyBuilder asmBuilder = domain.DefineDynamicAssembly(asmName, AssemblyBuilderAccess.Run);
    ModuleBuilder moduleBuilder = asmBuilder.DefineDynamicModule("MyModule");
    EnumBuilder enumBuilder = moduleBuilder.DefineEnum("MyNamespace.MyEnum", TypeAttributes.Public, typeof(int));

    for (int i = 0; i < strings.Length; ++i)
        enumBuilder.DefineLiteral(strings[i], i + 1);

    return enumBuilder.CreateType();
}

静的なenumとの書き方比較

enum Animal { Dog, Cat, Horse, Elephant }
string[] animalTable = new string[] { "Dog", "Cat", "Horse", "Elephant" };
System.Type enumType = BuildEnum(animalTable);

インスタンス生成

Animal animal;
System.Enum animal = (System.Enum)Activator.CreateInstance(enumType);

値の代入

animal = Animal.Cat;
animal = (System.Enum)enumType.GetField("Cat").GetValue(null);

文字列から値生成

animal = (Animal)System.Enum.Parse(typeof(Animal), "Horse");
animal = (System.Enum)System.Enum.Parse(enumType, "Horse");

int型との型変換

(注)例外処理は省略

int val = (int)animal;
animal = (Animal)val;
int val = (int)animal;
animal = (System.Enum)System.Convert.ChangeType(val, enumType);

おまけ

Unityエディタ拡張のEnumPopupメソッド

System.Enum newVal = (System.Enum)EditorGUILayout.EnumPopup(animal);

文字列のまま扱う場合はこちら↓

int oldIndex = ;
int newIndex = EditorGUILayout.Popup(oldIndex, animalTable);
23
18
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
23
18