enum 型をファイルに保存したり、UIなどのインデクスに対応させたりと、相互変換するとき確認したいことが多くあるので、備忘録的にまとめておいた。今回は通常の C# として書いているが、Unity などでも使用することは多いので、ちょっとしたトラブルシューティングなどもついでに。どちらかというとリファレンス的な使い方になると思うので、解説は少なめに凡例を列挙しておこう。
■enum → string 変換
■string → enum 変換
■enum → int 変換
■int → enum 変換
■enum の名前の配列を取得
■enum の値(enum)の配列オブジェクト(Array)を取得
■enum を long 型で使う
■enum の値割当と Unity インスペクタのずれを直す(Unity トラブルシューティング)
■enum の PlayerPrefs 保存と読み込み(Unity)
■string → enum 変換
■enum → int 変換
■int → enum 変換
■enum の名前の配列を取得
■enum の値(enum)の配列オブジェクト(Array)を取得
■enum を long 型で使う
■enum の値割当と Unity インスペクタのずれを直す(Unity トラブルシューティング)
■enum の PlayerPrefs 保存と読み込み(Unity)
(※) mono-4.2.1 (C#6, CLI4.5)[paiza.io] / Unity 5.6.3p1 - 2018.1.5f1 / Windows10(x64) で確認
■enum → string 変換
using System;
enum BloodType //※enum 型は任意
{
A, B, O, AB
}
//enum → string 変換
BloodType bloodType = BloodType.A;
string str = bloodType.ToString();
Console.WriteLine(str);
A
または以下のようにも書ける。
string str = Enum.GetName(typeof(BloodType), bloodType);
Console.WriteLine(str);
A
■string → enum 変換
using System;
enum BloodType //※enum 型は任意
{
A, B, O, AB
}
//string → enum 変換
string str = "B"; //"b" でも可
BloodType bloodType = (BloodType)Enum.Parse(typeof(BloodType), str, true); //true = IgnoreCase
Console.WriteLine(bloodType);
B
ちょっと試しに IgnoreCase のオプションを外して小文字にしてみると、System.ArgumentException が出る。
string str = "b";
//↓このコードはエラーが出ます。
BloodType bloodType = (BloodType)Enum.Parse(typeof(BloodType), str); //System.ArgumentException
Console.WriteLine(bloodType);
System.ArgumentException
■enum → int 変換
using System;
enum BloodType //※enum 型は任意
{
A, B, O, AB
}
//enum → int 変換
BloodType bloodType = BloodType.AB;
int i = (int)bloodType;
Console.WriteLine(i);
3
■int → enum 変換
using System;
enum BloodType //※enum 型は任意
{
A, B, O, AB
}
//int → enum 変換
int i = 3;
BloodType bloodType = (BloodType)Enum.ToObject(typeof(BloodType), i);
Console.WriteLine(bloodType);
AB
試しに範囲外の値を入れてみると、そのまま整数値が出てくる。
//int → enum 変換
int i = 4; //範囲外の値
BloodType bloodType = (BloodType)Enum.ToObject(typeof(BloodType), i);
Console.WriteLine(bloodType);
4
■enum の名前の配列を取得
using System;
enum BloodType //※enum 型は任意
{
A, B, O, AB
}
string[] names = Enum.GetNames(typeof(BloodType));
Console.WriteLine(string.Join(", ", names));
A, B, O, AB
■enum の値(enum)の配列オブジェクト(Array)を取得
using System;
enum BloodType //※enum 型は任意
{
A, B, O, AB
}
Array values = Enum.GetValues(typeof(BloodType));
foreach (var item in values) {
Console.WriteLine(item + " = " + (int)item);
}
A = 0
B = 1
O = 2
AB = 3
B = 1
O = 2
AB = 3
■enum を long 型で使う
using System;
enum LongRange : long //※enum 型は任意
{
Min = long.MinValue,
Num = 123456789L,
Max = long.MaxValue,
}
long min = (long)LongRange.Min; //キャストが必要
long num = (long)LongRange.Num; //キャストが必要
long max = (long)LongRange.Max; //キャストが必要
Console.WriteLine(min);
Console.WriteLine(num);
Console.WriteLine(max);
-9223372036854775808
123456789
9223372036854775807
123456789
9223372036854775807
■enum の値割当と Unity インスペクタのずれを直す(Unity トラブルシューティング)
例えば以下のような列挙型があったとき、途中から "Banana" を削除したくなったとしよう。しかし、コメントアウトで消したとするとそれぞれに割り当てられれた値がずれ、インスペクタでの表示(名前)も変わってしまう。
public enum Hoge //※enum 型は任意
{
Apple,
//Banana,
Cat,
Dog,
}
public Hoge hoge;
これは、コメントアウト前は {Apple = 0, Banana = 1, Cat = 2, Dog = 3} であったのに対し、コメントアウト後は {Apple = 0, Cat = 1, Dog = 2} になるために出る症状なので、以下のように値を直接割り当てれば、元の並びと同じになる。
public enum Hoge //※enum 型は任意
{
Apple,
//Banana,
Cat = 2,
Dog,
}
public Hoge hoge;
また列挙型はデフォルトでは0からの整数連番だが、値は自由に割り当てられるので、飛び番号や負の値なども使える。色々やってみると良いだろう。
■enum の PlayerPrefs 保存と読み込み(Unity)
Unity でユーザーデータとして enum 型の保存と読み込みをやってみよう。といっても内容的には先に述べた「enum←→stringの相互変換」をやっているだけである。ここでは Load と Save の機能を持ったメソッドを2つ作ったとする。シーンに UI-Button を2つ置いて、それぞれの OnClick() で呼び出すなどすれば、簡単に確認できるだろう。
using System;
using UnityEngine;
public enum Hoge { //※enum 型は任意
Apple,
Banana,
Cat,
Dog,
}
public Hoge hoge = Hoge.Apple;
string prefsName = "hoge";
public void LoadHoge() //UI-Button の OnClick に登録する等
{
string str = PlayerPrefs.GetString(prefsName, hoge.ToString());
hoge = (Hoge)Enum.Parse(typeof(Hoge), str);
Debug.Log("Loaded : " + hoge);
}
public void SaveHoge() //UI-Button の OnClick に登録する等
{
PlayerPrefs.SetString(prefsName, hoge.ToString());
PlayerPrefs.Save();
Debug.Log("Saved : " + hoge);
}
(インスペクタで「Banana」を選んで保存・読み込みをした場合)
Saved : Banana
Loaded : Banana
Saved : Banana
Loaded : Banana
ちなみに int 型で保存と読み込みをする場合には以下のように書ける。
・・・(略)・・・
public void LoadHoge()
{
int i = PlayerPrefs.GetInt(prefsName, (int)hoge);
hoge = (Hoge)Enum.ToObject(typeof(Hoge), i);
Debug.Log("Loaded : " + hoge + " (" + i + ")");
}
public void SaveHoge()
{
PlayerPrefs.SetInt(prefsName, (int)hoge);
PlayerPrefs.Save();
Debug.Log("Saved : " + hoge + " (" + (int)hoge + ")");
}
・・・(略)・・・
(インスペクタで「Banana」を選んで保存・読み込みをした場合)
Saved : Banana (1)
Loaded : Banana (1)
Saved : Banana (1)
Loaded : Banana (1)
string と int のどちらでも良いが、後から値の割当を変えたくなったときにも対応できるように、string 型で保存しておいた方が無難ではあるだろう(※public で宣言してる場合、後から変更するとインスペクタでの名前表示のずれが発生するので注意)。
(関連記事)
【Java】enum を int で取得する
【Java】文字列を enum 型に変換する
【Unity】色形式:Unity の Color と Android の ARGB(int32) の相互変換をする
トラックバックURL
http://fantom1x.blog130.fc2.com/tb.php/300-ff5b83da