きよくらの備忘録

「三日坊主と呼ばせない!日記」改め。主にソフトウェア開発関連の話題。

@functionsブロックはとっても強力

昨日ちらっと書きましたが、@functionsブロック*1はその名に反し(?)、単に内部でメソッドを定義するだけのものではありません。


公式?なドキュメントがどれかわからないのですが、きっと限りなく公式に近い(と勝手に思っている)のは以下でしょうか。
http://blogs.msdn.com/b/timlee/archive/2010/07/30/using-functions-in-an-asp-net-page-with-razor-syntax.aspx


また、id:shibayanからもアドバイスを頂きました。

@kiyokura 単純にクラス定義のスコープだと考えてもらえればいいかと。@functions でクラスや enum の定義も出来ます

(via @shibayan on twitter)

どんな感じになっているかは、Razorで記述した.cshtmlファイルがどんな形のオブジェクトになっているかを見ればわかりますね。cshtmlは実行時にC#で記述されたWebPageを継承したクラスに変換されてからコンパイルされるので、その中で@functionsに記述したものを見ると、普通にページクラスのメンバとして展開されていることが割ります*2*3



そういえば@functions、Betaの時に無かった仕様のせいか、「Razor 構文とASP.NET Webページ*4」にも記載されていません。私自身、この構文の存在を知るまでは、ページ内のスコープ((@{}ブロックと@functionsの両方のスコープで有効なメンバをどう定義するか))をどう実現すべきか悩みました。正解は『@functionsに全部書いてしまえ』ってことですね。


P.S.
あと、これ、@functionsって名前はあんまりよくないというか、誤解を受けそう。例えば「@pagelocal」とかの方が良さそうな気がするんですが:P

*1:VBの時は@Functions

*2:実際、これまた昨日、id:shibayan(@shibayan)にアドバイスをしてもらいつつ、razorで記述したcshtmlから作成されたcsファイルを覗いて確認しました。

*3:ちなみに、通常の@{}のブロックに書かれたものは、ページを処理するメソッド内に展開されますので、スコープとしてはその中だけになります。

*4:http://msdn.microsoft.com/ja-jp/asp.net/gg193039