kazuk は null に触れてしまった

C# / .NET 系技術ネタ縛りでお送りしております

csproj.user を作るための T4 テンプレート


スイカドライブに BuildOptions.tt なるものを投下いたしましたのでご案内。
(またリンクを Spaces が消したら Blog の移転を考えるなう)
 
 デバッグモードを持っていて、デバッグモード時には msbuild を実行してログを取って BuildOptions.txt に吐き出してくれますので、編集して保存(T4 では save is execute なのだよ)の繰り返しでパタパタといじっていけるはずです。デバッグモードでない場合にはこんなのを csproj.user に吐いたよと BuildOptions.txt に吐き出します。
 
こいつに色々と盛り込まれている 「よく訓練されたT4使いになる為のあれこれ」 をご紹介しましょう。
 
  1. よく訓練されたT4使いは 「何を元に作るか」 「何を作るか」 だけを考える。

    <# Generate( (何を元に作るか), (o)=>{#> 何を作るか <#} ); #> と書く。

    ファイルの最後に飛んで以下のように書く。

    <#+
    void Generate<T>( IEnumerable<T> seq, Action<T> action )
    {
        foreach( var item in seq ) { action(item) };
    }
    #>

    ポイントは T4 のコードブロック中で (value)=>{#> むにゃむにゃ <#} は立派な Action<T> な statement lambda だという事です。

    何を元に作るかはきっと from … select になるでしょう。 何を作るかの中では <#=o.Property#> で値を出力する事ができます。

  2. よく訓練されたT4使いは TextTemplate クラスの外にコードを置ける

    さて、<#@ include filename=""> でこんなファイルを取り込むとします。

    <#+ } 

    // ここはクラスの外!

    public partial class 読み込み元のTTのクラス名 { #>

    1で作った Generate メソッドを IEnumerable<T> に対する拡張メソッドにするとかそんな事しちゃいけません。ダメ、絶対。

  3. よく訓練されたT4使いは T4 の Write を殺す

    今回はやってませんけど(出力はxmlとtextだし、改行の調整とか必要無いから)、習慣としてファイル末尾で

    <#+
    public new void Write( string value )
    {
        GenerationEnvironment.Append( value.Replace( Environment.NewLine, Environment.NewLine+CurrentIndent );
    }
    #>

    するほうが良いです。
    VS2010 使いの人は CustomTool を GeneratorからPreprocessor に変えると cs ファイルを得る事ができますが、 Base のWrite は色々ごちゃごちゃやっていて結果を想像するのが大変だし、なんだかなーです。

  4. よく訓練された T4 使いは ToStringHelper に絶望している。

    3と似たりよったりですが、partial がついてなかったり、ToStringWithCulture に virtual をMSの中の人が付け忘れたせいで bool は TrueとかFalse とか出るし、null に対して "null" と文字列を出すとかもできません。なんかオブジェクトだすとクラス名だけになっちゃったり。List<T>とか出すと <#@ output extention=".il" #> がお勧めですか!って文字列になります。

  5. よく訓練された T4 使いは IFormatProvider にも絶望している。

    System.Boolean.ToString( IFormatProvider )

    解説


    provider パラメータは予約されています。このパラメータは、このメソッドの実行には関与しません。

  6. (Added 2010/8/15) 良く訓練された T4 使いは脱獄する

    脱獄キットをリリースしました

  7. よく訓練された T4 使いは Preprocessor かけてから Write(ToStringHelper.ToStringWithCulture( を置換する

    (もうT4じゃなくなってるという突っ込みは許可しない)

  8. よく訓練された T4 使いは TextTemplatingFileGenerator をレジストリ検索して…

    「HOWTO: Visual Studio のカスタムツールの作り方 (C#) 」ってMSDNドキュメントとか、KBどっかに無いもんか?

まぁ、後半は冗談交じりですがこんな感じです。

VS2010 への移行がらみで CLR2 と CLR4 の両方をターゲットにビルドしたいとか色々ありげな今日この頃、皆様の助けとなる tt であるかなーとかいう事で。TTファイルは以下

( やっぱり消えた、僕の SkyDrive の public にあるからどーぞ )

以下、余談。

そうそう、CLR 4.0 (mscorlib 4.0) で string は真に imuttable になりましたねー

CLR2 の間は「string は imuttable だから」とか書いてあると鼻で笑ってしまう僕だったのですが、もうそんな事も無くなって良いことです。

え? って思ったアナタは mscorlib 2.0 の StringBuilder の Append にデバッガで step-in してみる事をお勧めします。

CLR2.0 においての StringBuilder は「String.AppendInplace へのアクセスヘルパであり、capacity overflow に対する failsafe を提供するクラス」で、String は imuttable でなく repeatly editableだったんですよ。(ΩΩΩΩ< な、なんだってー)

StringBuilder の m_StringValue が無くなった事で動かなくなったコードが(アワワワワ

ちなみに超パフォーマンススペシフィックなシチュエーションに対してよく訓練された .NET er は

public static class StringBuilderExtention
{
    /// <summary>
    ///  ToString と同じ動作だけど、ここでコピーが発生するって事を示す為にワザトextentionする
    /// </summary>
    public static string CopyString( this StringBuilder sb ) { return sb.ToString(); }
}

とか、コピーを避ける為に m_StringValue を取り出して使うとかしてたりしてなかったり…

コメントを残す