(:3[kanのメモ帳]

個人ゲーム開発者kan.kikuchiのメモ的技術ブログ。月木更新でUnity関連がメイン。

enumをジェネリック(Generics)で使う際のアレコレ【C#】


このエントリーをはてなブックマークに追加

はじめに

今回は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))) {
    
  }

}


参考