C#のGenericsのオーバーロードが便利だった話
C#の技術記事。コード内容はUnity寄り。
コルーチンをまとめたクラスを設計していて、
AddRoutine (Func<IEnumerator> routine)
みたいなコードを書いた。
これは、たとえば
IEnumerator RoutineA () { ... } void Main () { var routines = CoroutineContainer(); routines.AddRoutine(RoutineA); }
みたいなのを書けるようにするためのコード。
で、この場合RoutineAが引数を持ってないからいいんだけど、
IEnumerator RoutineB (int arg) { ... }
とか
IEnumerator RoutineC (string arg) { ... }
とかの
引数ありのコルーチンって結構ある。
で、じゃあ
AddRoutine (Func<int,IEnumerator> routine, int arg)
と
AddRoutine (Func<string,IEnumerator> routine, string arg)
の
2つを定義しておけば、intとstringは対応できる。
でも、他の型でも対応したい。型指定しないで使えるようにしたいって思った。
そんなときのためにGenericsという仕組みがあったのだった。
AddRoutine<T> (Func<T,IEnumerator> routine, T arg)
こいつを定義しておけば、さっきの2つのオーバーロードは必要なくなる。
こいつを使ってRoutineBをAddRoutineしたいときは、
routines.AddRoutine<int>(RoutineB, x);
みたいに書けばいい。
しかしGenericsの良さはとどまるところを知らなかった。
C#は型推論の仕組みがあり、Genericsの指定も省略できる。
つまり、一つ上の例では、x
がintなら、このように書ける。
routines.AddRoutine(RoutineB, x);