tonari note

オンラインゲームエンジニアの雑記

T4の話

お久しぶりです。
今日はIDEのT4の機能についてお話しようと思います。

さて、C#はひとつの言語ですが、僕はC#は.NETやMonoなどの実行環境、VisualStudioやXamarinなどのIDEとセットで考えるべきだと思っています。
C#C++などに比べてさまざまな制限があり、また中間言語JITなどを挟むのでエンジニアの意のままに操るという意味ではそうも行かない言語です。
ですが、ネイティブな環境に比べて、先のJIT中間言語などを実行してくれる、またIDEなどによって開発をサポートしてくれる機能を見方にすれば、今のところ製品を作成するのには最善の環境群ではないでしょうか。

今回のT4はC#だけで使えるものはないのですが、せっかくなのでC#でお話しようと思います。

まず、VisualStudioやMonoDevelopからプロジェクトを作成し、新規ファイルの追加をするとこのようなメニューが出てくるかと思います。
f:id:ykimisaki:20131207032802p:plain
f:id:ykimisaki:20131207032809p:plain
これがT4ファイルになります。
拡張子は.ttです。

使いどころとしては、たとえばC#の構造体などの場合、以下の特徴があります。
・クラスや他の構造体からの継承ができない。
・他のクラスや構造体に継承が出来ない。
・クラスのような参照渡しではなく、値渡しになる。
・値渡しのコピーコストゆえに巨大なオブジェクトには向かない。
・ボックス化に対するパフォーマンスを考えざるを得なくなる。
・ヒープではなくスタックに確保されるため、配列などにした場合はパフォーマンスが良い。

ボックス化に関してはまた別の機会に書きたいと思いますが、このボックス化を回避するにおいてこのT4は非常に役に立ちます。
たとえば、ゲームだと32ビットの整数をラップした「ItemID」や「CharacterID」など、全く同じ挙動をするけども構造体の場合のほうがパフォーマンス的に好ましい、けど型安全にしたい場合があります。
またこれらはIEquatable演算子オーバーロードを実装したり、ToStringメソッドをオーバーライドする場合が多いです。
インターフェイスやobject型にキャストすることは上のボックス化を引き起こします。
これはよろしくないです。

IDにしても良いのですが、これもまた意外と面倒くさい。
そこでC++であればstrong typedefでいけるかと思うのですが、C#の場合はT4で解決します。

f:id:ykimisaki:20131207033455p:plain

少し難しいですが、左のTTファイルにテンプレートを作成すると、右の.csに展開してくれるようになります。
説明が難しいですが、実際に作業してもらえるとすぐにわかるかと思います。

T4はC#専用のものではなく「テキストとして吐き出す」ものですので、使いようによってはC++やF#などさまざまな言語に応用することが出来ます。
ただし、T4を記述するためのスクリプト言語としては、C#VBのみのサポートになっています。

詳しくはこちらをごらんください。
http://msdn.microsoft.com/ja-jp/magazine/hh975350.aspx