案外情報が少なかった気がするのでまとめてみた。
ほとんどのことは文字列テーブルでも動的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);