はじめに
今回はenumをジェネリック(Generics)で使いたい時の話。
ちなみにジェネリックとは、いろいろな型に対応したい時に使うものです。
型だけ違って処理の内容が同じようなものを作るときに使う。
つまり以下のように色々なenumに対応したいという場合の話です。
//アイテムの種類 public enum ItemType { Weapon, Armor, Drug } //動物の種類 public enum AnimalType { Dog, Cat }
//ジェネリックなメソッド public void GenericsMethod<T>(T t){ /*処理*/ }
GenericsMethod(ItemType.Weapon); GenericsMethod(AnimalType.Dog);
enumをジェネリックで使う際のアレコレ
最初の例だと、入力はどんな型でも良いので非常に危険です。
一応、whereを使う事で型の制限は可能ですが、
残念ながらenumに限定するという事は出来ないようです。
しかし、enumはstruct(構造体)なので、
whereでstructを指定することで、ある程度の制限をする事は可能です。
//ジェネリックなメソッド(入力Tはstructのみ) public void GenericsMethod<T>(T t) where T : struct{ /*処理*/ }
ただ、当たり前ですが普通のstructも入力出来てしまうので、
TypeのisEnumを使ってenum以外が入力された場合も考慮すると、なお良いかもしれません。
//ジェネリックなメソッド(入力Tはstructのみ) public void GenericsMethod<T>(T t) where T : struct{ //入力がenumか判定 Type type = typeof(T); if(!type.IsEnum){ /*enumじゃない時の処理(エラーとか)*/ return; } /*入力がenumの時の処理*/ }
また、入力された各enumごとに処理したい場合は以下のような感じ。
//ジェネリックなメソッド(入力Tはstructのみ) public void GenericsMethod<T>(T t) where T : struct{ //入力がItemType if (typeof(T) == typeof(ItemType)) { } //入力がAnimalType else if (typeof(T) == typeof(AnimalType)) { } }
さらに、入力されたものを元の型に戻したい場合は以下のような感じ。
//ジェネリックなメソッド(入力Tはstructのみ) public void GenericsMethod<T>(T t) where T : struct{ //入力がItemType if (typeof(T) == typeof(ItemType)) { //ItemTypeに戻す(Enumを使うのに using System; が必要) ItemType itemType = (ItemType)Enum.Parse(typeof(ItemType), t.ToString()); } }
ジェネリックとは関係ないですが、enumのループもついでに以下のような感じ。
//ジェネリックなメソッド(入力Tはstructのみ) public void GenericsMethod<T>(T t) where T : struct{ //enumのループ(Enumを使うのに using System; が必要) foreach (T tt in Enum.GetValues(typeof(T))) { } }
参考