<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C#</title><link>http://www.ailight.jp/blog/kazuk/category/191.aspx</link><description>C#言語についてのこと</description><managingEditor>菊池</managingEditor><dc:language>ja-JP</dc:language><generator>.Text Version 0.95.2004.102</generator><item><dc:creator>菊池</dc:creator><title>using の謎</title><link>http://www.ailight.jp/blog/kazuk/archive/2009/12/09/28109.aspx</link><pubDate>Wed, 09 Dec 2009 04:43:00 GMT</pubDate><guid>http://www.ailight.jp/blog/kazuk/archive/2009/12/09/28109.aspx</guid><wfw:comment>http://www.ailight.jp/blog/kazuk/comments/28109.aspx</wfw:comment><comments>http://www.ailight.jp/blog/kazuk/archive/2009/12/09/28109.aspx#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.ailight.jp/blog/kazuk/comments/commentRss/28109.aspx</wfw:commentRss><trackback:ping>http://www.ailight.jp/blog/kazuk/services/trackbacks/28109.aspx</trackback:ping><description>&lt;P&gt;といっても IDisposable のほうで無くて、type aliase のほう&lt;/P&gt;
&lt;P&gt;using Hoge = string;&lt;/P&gt;
&lt;P&gt;error CS1041: 識別子が必要です。キー ワードは&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 'string' です&lt;/P&gt;
&lt;P&gt;using Hoge = System.String;&lt;/P&gt;
&lt;P&gt;compile success&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;なんで？&lt;/P&gt;&lt;img src ="http://www.ailight.jp/blog/kazuk/aggbug/28109.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>菊池</dc:creator><title>メモリ帯域とCPUキャッシュの効率が問題だ</title><link>http://www.ailight.jp/blog/kazuk/archive/2009/11/19/28084.aspx</link><pubDate>Thu, 19 Nov 2009 03:51:00 GMT</pubDate><guid>http://www.ailight.jp/blog/kazuk/archive/2009/11/19/28084.aspx</guid><wfw:comment>http://www.ailight.jp/blog/kazuk/comments/28084.aspx</wfw:comment><comments>http://www.ailight.jp/blog/kazuk/archive/2009/11/19/28084.aspx#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.ailight.jp/blog/kazuk/comments/commentRss/28084.aspx</wfw:commentRss><trackback:ping>http://www.ailight.jp/blog/kazuk/services/trackbacks/28084.aspx</trackback:ping><description>&lt;P&gt;&lt;A href="http://social.msdn.microsoft.com/Forums/ja-JP/csharpgeneralja/thread/94173254-e79c-47ad-8fbd-98c421aa74d9/"&gt;http://social.msdn.microsoft.com/Forums/ja-JP/csharpgeneralja/thread/94173254-e79c-47ad-8fbd-98c421aa74d9/&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;の問題がなかなか面白い。&lt;/P&gt;
&lt;P&gt;ループ回数が膨大＝i,j の軸が結構長いと仮定すると&lt;/P&gt;
&lt;P&gt;多分 CPU のキャッシュが実質として効いてない（効かない）のが最初の問題で、メモリ帯域に率速してしまっているのが性能問題の主因だろう。&lt;/P&gt;
&lt;P&gt;変化は一方向に伝搬しているように見える(i を更新して i-1 で見てる、j+1を元にjに反映)のでブロックごとに演算して CPU キャッシュを効かせてあげる＆依存関係から外れる所を並列化の対象とすると良いんだけど、実コードに落とすとなると結構難しい。&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;img src ="http://www.ailight.jp/blog/kazuk/aggbug/28084.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>菊池</dc:creator><title>Quick Hack: SketchFlow for ASP.NET MVCの様なもの</title><link>http://www.ailight.jp/blog/kazuk/archive/2009/11/16/28076.aspx</link><pubDate>Mon, 16 Nov 2009 02:46:00 GMT</pubDate><guid>http://www.ailight.jp/blog/kazuk/archive/2009/11/16/28076.aspx</guid><wfw:comment>http://www.ailight.jp/blog/kazuk/comments/28076.aspx</wfw:comment><comments>http://www.ailight.jp/blog/kazuk/archive/2009/11/16/28076.aspx#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.ailight.jp/blog/kazuk/comments/commentRss/28076.aspx</wfw:commentRss><trackback:ping>http://www.ailight.jp/blog/kazuk/services/trackbacks/28076.aspx</trackback:ping><description>&lt;P&gt;タイトル通りにちょっとQuick Hackしてみた。&lt;/P&gt;
&lt;P&gt;SketchFlow ってのは &lt;A href="http://www.atmarkit.co.jp/news/200907/16/remix.html"&gt;画面遷移もカンタン設計、MSが新ツールをデモ － ＠IT&lt;/A&gt;&amp;nbsp;とかにざっくりした概要はあるが要するに画面フローをWPF / SilverLight プロジェクトのプロトタイピングとして簡単にできるツールなわけで Expression Blend 3 についてる新機能です。&lt;/P&gt;
&lt;P&gt;んで、画面フローをプロトタイピングして、その結果として「これでこの機能できるよねー」とかの検証をしたうえで実装に入るという開発プロセスを踏むわけです。&lt;/P&gt;
&lt;P&gt;んで、検証された画面フローの使い道を WPF / SilverLight に限定してしまうのはモッタイナイというわけでやってみたちゅーこと。&lt;/P&gt;
&lt;P&gt;手順は簡単で最初にとにかく適当に画面フローを SketchFlowで書いてみる。それをBlendからビルドして試しに動かしてみる。この辺入念に。&lt;/P&gt;
&lt;P&gt;納得行く動きをする画面フローができたらおもむろに Blend を終了して、 Sketch.Flow ファイルを Visual Studio で開く。&lt;/P&gt;
&lt;P&gt;なんてこたーないXMLが出てくるので XML メニューからスキーマを生成させて、xsd を保存。&lt;/P&gt;
&lt;P&gt;XSDを&lt;A href="http://visualstudiogallery.msdn.microsoft.com/ja-JP/33D43486-E73A-4F64-A342-F32C702ABC19"&gt;Liquid XML Studio&lt;/A&gt;で読み込んで重要になりそうな要素を選んで右クリックでRefactor -&amp;gt; Convert to Global Type で型を割りつける。&lt;/P&gt;
&lt;P&gt;自分は Data/Screens 配下の Screen と Data/Connections配下のConnectionが重要とみて実行。（QuickHackなので名前なんて気にしない、デフォルトで出た ScreenType、ConnectionType を名前としてそのまま使った）&lt;/P&gt;
&lt;P&gt;XMLを見てみると Screen のTypeがNavigationな物が画面なんで、その画面に対してテンプレートを作る。&lt;/P&gt;
&lt;BLOCKQUOTE style="MARGIN-RIGHT: 0px" dir=ltr&gt;
&lt;P&gt;$@query &lt;BR&gt;&amp;nbsp; from ScreenType s in input.Screens where s.Type=="Navigation" select new { filename=s.ClassName+".aspx" , item=s }&lt;BR&gt;@$&lt;BR&gt;$@itemType ScreenType&lt;BR&gt;&amp;lt;html&amp;gt;&lt;BR&gt;&amp;lt;head&amp;gt;&lt;BR&gt;&amp;lt;title&amp;gt;$=item.DisplayName$&amp;lt;/title&amp;gt;&lt;BR&gt;&amp;lt;/head&amp;gt;&lt;BR&gt;&amp;lt;body&amp;gt;&lt;BR&gt;&amp;lt;h1&amp;gt;$=item.DisplayName$&amp;lt;/h1&amp;gt;&lt;BR&gt;&amp;lt;p&amp;gt;リンク&amp;lt;/p&amp;gt;&lt;BR&gt;$@list( ConnectionType conn in from c in input.Connections where c.Type=="Navigation" &amp;amp;&amp;amp; c.Source==item.ClassName select c )$&lt;BR&gt;&amp;lt;% = Html.ActionLink("$= input.Screens.Single( s=&amp;gt;s.ClassName==conn.Target ).DisplayName$", "$=conn.Target$") %&amp;gt;&lt;BR&gt;$ @$&lt;BR&gt;&amp;lt;p&amp;gt;埋め込み&amp;lt;/p&amp;gt;&lt;BR&gt;$@list( ConnectionType conn in from c in input.Connections where c.Type=="Composition" &amp;amp;&amp;amp; c.Source==item.ClassName select c )$&lt;BR&gt;&amp;lt;% Html.RenderPartial("$= input.Screens.Single( s=&amp;gt;s.ClassName==conn.Target ).ClassName$"); %&amp;gt;&amp;lt;br/&amp;gt;&lt;BR&gt;$ @$&lt;/P&gt;
&lt;P&gt;&amp;lt;/body&amp;gt;&lt;BR&gt;&amp;lt;/html&amp;gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;こいつは csxっていう自作のコードジェネレータジェネレータの為のテンプレート。要するに画面のクラス名に従って aspx を吐きだしてくれる。内部にはConnections配下にあるConnectionを元にNavigationをリンクとしてまとめて出してくれて、Composition として ascx への RenderPartial を吐く。&lt;/P&gt;
&lt;P&gt;同様に Composition を&lt;/P&gt;
&lt;BLOCKQUOTE style="MARGIN-RIGHT: 0px" dir=ltr&gt;
&lt;P&gt;$@query &lt;BR&gt;&amp;nbsp; from ScreenType s in input.Screens where s.Type=="Navigation" select new { filename=s.ClassName+".aspx" , item=s }&lt;BR&gt;@$&lt;BR&gt;$@itemType ScreenType&lt;BR&gt;&amp;lt;html&amp;gt;&lt;BR&gt;&amp;lt;head&amp;gt;&lt;BR&gt;&amp;lt;title&amp;gt;$=item.DisplayName$&amp;lt;/title&amp;gt;&lt;BR&gt;&amp;lt;/head&amp;gt;&lt;BR&gt;&amp;lt;body&amp;gt;&lt;BR&gt;&amp;lt;h1&amp;gt;$=item.DisplayName$&amp;lt;/h1&amp;gt;&lt;BR&gt;&amp;lt;p&amp;gt;リンク&amp;lt;/p&amp;gt;&lt;BR&gt;$@list( ConnectionType conn in from c in input.Connections where c.Type=="Navigation" &amp;amp;&amp;amp; c.Source==item.ClassName select c )$&lt;BR&gt;&amp;lt;% = Html.ActionLink("$= input.Screens.Single( s=&amp;gt;s.ClassName==conn.Target ).DisplayName$", "$=conn.Target$") %&amp;gt;&lt;BR&gt;$ @$&lt;BR&gt;&amp;lt;p&amp;gt;埋め込み&amp;lt;/p&amp;gt;&lt;BR&gt;$@list( ConnectionType conn in from c in input.Connections where c.Type=="Composition" &amp;amp;&amp;amp; c.Source==item.ClassName select c )$&lt;BR&gt;&amp;lt;% Html.RenderPartial("$= input.Screens.Single( s=&amp;gt;s.ClassName==conn.Target ).ClassName$"); %&amp;gt;&amp;lt;br/&amp;gt;&lt;BR&gt;$ @$&lt;/P&gt;
&lt;P&gt;&amp;lt;/body&amp;gt;&lt;BR&gt;&amp;lt;/html&amp;gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;ってやり（それぞれ適当にtemplateを拡張子として保存）&lt;/P&gt;
&lt;P&gt;&amp;gt;"c:\Program Files\csx\csx.exe" -xsd:Sketch.xsd -generateExe -schemaRoot:Data *.template&lt;/P&gt;
&lt;P&gt;でコードジェネレータを作って&lt;/P&gt;
&lt;P&gt;&amp;gt;Sketch.exe Sketch.Flow&lt;/P&gt;
&lt;P&gt;で実行。&lt;/P&gt;
&lt;P&gt;めでたくプロトタイプ通りの aspx と ascx が得られましたとさ。&lt;/P&gt;
&lt;P&gt;xaml を解釈してもっと細かいデータ取ればより細かい生成制御はできると思う＆人手でのデザイン(HTMLコーディング)と機械生成する部分の調整をしないと駄目なんだろうけど、Quick Hack としてはまず成功。&lt;/P&gt;
&lt;P&gt;というわけで、斜め上に間違えたSketchFlowの使い方でした。&lt;/P&gt;
&lt;P&gt;Let's Enjoy Generate Code!&lt;/P&gt;&lt;img src ="http://www.ailight.jp/blog/kazuk/aggbug/28076.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>菊池</dc:creator><title>新人採用…終了？</title><link>http://www.ailight.jp/blog/kazuk/archive/2009/11/06/28049.aspx</link><pubDate>Fri, 06 Nov 2009 07:21:00 GMT</pubDate><guid>http://www.ailight.jp/blog/kazuk/archive/2009/11/06/28049.aspx</guid><wfw:comment>http://www.ailight.jp/blog/kazuk/comments/28049.aspx</wfw:comment><comments>http://www.ailight.jp/blog/kazuk/archive/2009/11/06/28049.aspx#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.ailight.jp/blog/kazuk/comments/commentRss/28049.aspx</wfw:commentRss><trackback:ping>http://www.ailight.jp/blog/kazuk/services/trackbacks/28049.aspx</trackback:ping><description>&lt;P&gt;というわけで、&lt;A href="http://www.ailight.jp/blog/kazuk/archive/2009/10/07/28010.aspx"&gt;また社員募集しています&lt;/A&gt;&amp;nbsp;での採用も大方終了しました。&lt;/P&gt;
&lt;P&gt;いつもの事で　Joel テストに従って書き問題をやったので問題を晒してみます。&lt;/P&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P style="MARGIN: 0in; FONT-SIZE: 10pt"&gt;&lt;SPAN style="FONT-FAMILY: Verdana" lang=en-US&gt;CSV&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 'MS Gothic'" lang=ja&gt;の生成&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN: 0in; FONT-FAMILY: 'MS Gothic'; FONT-SIZE: 10pt"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="MARGIN: 0in; FONT-SIZE: 10pt"&gt;&lt;SPAN style="FONT-FAMILY: 'MS Gothic'" lang=ja&gt;　以下の仕様に基づいて&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: Verdana" lang=en-US&gt;CSV&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 'MS Gothic'" lang=ja&gt;出力を行うコードを実装して下さい。（記述言語は問いません）&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN: 0in; FONT-FAMILY: 'MS Gothic'; FONT-SIZE: 10pt"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="MARGIN: 0in; FONT-FAMILY: 'MS Gothic'; FONT-SIZE: 10pt"&gt;・文字列と数値からなるデータを出力する&lt;/P&gt;
&lt;P style="MARGIN: 0in; FONT-FAMILY: 'MS Gothic'; FONT-SIZE: 10pt"&gt;・各レコードは改行で区切られる（以下例外あり）&lt;/P&gt;
&lt;P style="MARGIN: 0in; FONT-SIZE: 10pt"&gt;&lt;SPAN style="FONT-FAMILY: 'MS Gothic'" lang=ja&gt;・文字列はダブルクォート&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: Verdana" lang=en-US&gt;(")&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 'MS Gothic'" lang=ja&gt;で囲まれる&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN: 0in; FONT-SIZE: 10pt"&gt;&lt;SPAN style="FONT-FAMILY: 'MS Gothic'" lang=ja&gt;・文字列内で&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: Verdana" lang=en-US&gt;2&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 'MS Gothic'" lang=ja&gt;つの連続するダブルクォートを一つのダブルクォートのエスケープとして扱う&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN: 0in; FONT-FAMILY: 'MS Gothic'; FONT-SIZE: 10pt"&gt;・文字列内での改行が許される&lt;/P&gt;
&lt;P style="MARGIN: 0in; FONT-FAMILY: 'MS Gothic'; FONT-SIZE: 10pt"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="MARGIN: 0in; FONT-FAMILY: Verdana; FONT-SIZE: 10pt" lang=en-US&gt;public struct Field { &lt;/P&gt;
&lt;P style="MARGIN: 0in; FONT-SIZE: 10pt"&gt;&lt;SPAN style="FONT-FAMILY: Verdana" lang=en-US&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;public bool IsString; // &lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 'MS Gothic'" lang=ja&gt;要素が&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: Verdana" lang=en-US&gt; string &lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 'MS Gothic'" lang=ja&gt;の場合には&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: Verdana" lang=en-US&gt; true&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN: 0in; FONT-FAMILY: Verdana; FONT-SIZE: 10pt" lang=en-US&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;public string StringValue;&lt;/P&gt;
&lt;P style="MARGIN: 0in; FONT-FAMILY: Verdana; FONT-SIZE: 10pt" lang=en-US&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;public int IntegerValue;&lt;/P&gt;
&lt;P style="MARGIN: 0in; FONT-FAMILY: Verdana; FONT-SIZE: 10pt" lang=en-US&gt;}&lt;/P&gt;
&lt;P style="MARGIN: 0in; FONT-FAMILY: Verdana; FONT-SIZE: 10pt" lang=en-US&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="MARGIN: 0in; FONT-FAMILY: 'ＭＳ ゴシック'; FONT-SIZE: 10pt"&gt;において、以下のメソッド形式で実装して下さい。&lt;/P&gt;
&lt;P style="MARGIN: 0in; FONT-FAMILY: 'ＭＳ ゴシック'; FONT-SIZE: 10pt"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="MARGIN: 0in; FONT-FAMILY: Verdana; FONT-SIZE: 10pt" lang=en-US&gt;public static void WriteCsv( string pathName, IEnumerable&amp;lt; Field[] &amp;gt; records )&lt;/P&gt;
&lt;P&gt;こんな感じ。&lt;/P&gt;
&lt;P&gt;P.S.&lt;/P&gt;
&lt;P&gt;BCL4.0ではストリームがIEnumerable食えるようになるらしいねー&lt;/P&gt;
&lt;P&gt;だからと言って&lt;/P&gt;
&lt;P&gt;using(&amp;nbsp;var sw = new StreamWriter( pathName ) ) sw.WriteLines(&amp;nbsp;from rec in records&amp;nbsp;let recString = (from field in rec&amp;nbsp;select field.IsString&amp;nbsp;? "\""+ field.StringValue.Replace("\"","\"\"") +"\""&amp;nbsp;: field.IntegerValue.ToString() ) ).Join(",") select recString );&lt;/P&gt;
&lt;P&gt;とかワンライナーやる奴は某誰かと同類という事でご遠慮いただけると幸いです。&lt;/P&gt;&lt;img src ="http://www.ailight.jp/blog/kazuk/aggbug/28049.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>菊池</dc:creator><title>今度はT16までだ</title><link>http://www.ailight.jp/blog/kazuk/archive/2009/10/27/28039.aspx</link><pubDate>Tue, 27 Oct 2009 04:46:00 GMT</pubDate><guid>http://www.ailight.jp/blog/kazuk/archive/2009/10/27/28039.aspx</guid><wfw:comment>http://www.ailight.jp/blog/kazuk/comments/28039.aspx</wfw:comment><comments>http://www.ailight.jp/blog/kazuk/archive/2009/10/27/28039.aspx#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.ailight.jp/blog/kazuk/comments/commentRss/28039.aspx</wfw:commentRss><trackback:ping>http://www.ailight.jp/blog/kazuk/services/trackbacks/28039.aspx</trackback:ping><description>&lt;P&gt;&lt;A href="http://msdn.microsoft.com/en-us/library/dd402862(VS.100).aspx"&gt;Func(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, TResult) Delegate (System)&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;きたーーー！&lt;/P&gt;
&lt;BLOCKQUOTE style="MARGIN-RIGHT: 0px" dir=ltr&gt;
&lt;P&gt;public static Expression&amp;lt;Func&amp;lt;TResult&amp;gt;&amp;gt; AsExpression( Expression&amp;lt;Func&amp;lt;TResult&amp;gt;&amp;gt; expression ) { return expression }&lt;BR&gt;public static Expression&amp;lt;Func&amp;lt;T1,TResult&amp;gt;&amp;gt; AsExpression( Expression&amp;lt;Func&amp;lt;T1,TResult&amp;gt;&amp;gt; expression ) { return expression }&lt;BR&gt;&amp;#8230; Func のT4まであるパターンに従って作る&lt;/P&gt;
&lt;P&gt;&lt;A href="http://www.ailight.jp/blog/kazuk/archive/2009/07/24/27962.aspx"&gt;Where に埋め込む為に Expression Tree をさらにこねる&lt;/A&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P dir=ltr&gt;なんて事をやっていたみなさん、お仕事４倍のお時間がやってまいりました。&lt;/P&gt;
&lt;P dir=ltr&gt;通常の３倍で消化をお願いします。（ぉぃ&lt;/P&gt;
&lt;P dir=ltr&gt;この辺、なんとかならんもんなんでしょうか。&lt;/P&gt;&lt;img src ="http://www.ailight.jp/blog/kazuk/aggbug/28039.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>菊池</dc:creator><title>これはやりすぎだろ</title><link>http://www.ailight.jp/blog/kazuk/archive/2009/10/23/28032.aspx</link><pubDate>Fri, 23 Oct 2009 08:06:00 GMT</pubDate><guid>http://www.ailight.jp/blog/kazuk/archive/2009/10/23/28032.aspx</guid><wfw:comment>http://www.ailight.jp/blog/kazuk/comments/28032.aspx</wfw:comment><comments>http://www.ailight.jp/blog/kazuk/archive/2009/10/23/28032.aspx#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.ailight.jp/blog/kazuk/comments/commentRss/28032.aspx</wfw:commentRss><trackback:ping>http://www.ailight.jp/blog/kazuk/services/trackbacks/28032.aspx</trackback:ping><description>&lt;P&gt;&lt;A href="http://weblogs.asp.net/scottgu/archive/2009/10/22/vs-2010-code-intellisense-improvements-vs-2010-and-net-4-0-series.aspx"&gt;VS 2010 Code Intellisense Improvements (VS 2010 and .NET 4.0 Series) - ScottGu's Blog&lt;/A&gt;&amp;nbsp;より&lt;/P&gt;
&lt;BLOCKQUOTE style="MARGIN-RIGHT: 0px" dir=ltr&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;U&gt;Pascal Case Intellisense&lt;/U&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;The .NET Framework naming guidelines specify that type and member names should be &amp;#8220;Pascal Cased&amp;#8221; by default.&amp;nbsp; This means that each word in a type or member should start with a capitalized letter (for example: &lt;STRONG&gt;P&lt;/STRONG&gt;age&lt;STRONG&gt;I&lt;/STRONG&gt;ndex&lt;STRONG&gt;C&lt;/STRONG&gt;hanged).&amp;nbsp; &lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P dir=ltr&gt;おいおい、これはいくらなんでもやりすぎだろー。&lt;/P&gt;
&lt;P dir=ltr&gt;ANE (ArgumentNullException)とか、 SCEA(SelectionChangedEventArgs) とか、AOORE (ArgumentOutOfRangeException)とか。&lt;/P&gt;
&lt;P dir=ltr&gt;超絶略語の飛び交うさまが目に浮かぶ。&lt;/P&gt;&lt;img src ="http://www.ailight.jp/blog/kazuk/aggbug/28032.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>菊池</dc:creator><title>.NET Reactive Framework を Enjoy! してみた</title><link>http://www.ailight.jp/blog/kazuk/archive/2009/08/18/27983.aspx</link><pubDate>Tue, 18 Aug 2009 11:25:00 GMT</pubDate><guid>http://www.ailight.jp/blog/kazuk/archive/2009/08/18/27983.aspx</guid><wfw:comment>http://www.ailight.jp/blog/kazuk/comments/27983.aspx</wfw:comment><comments>http://www.ailight.jp/blog/kazuk/archive/2009/08/18/27983.aspx#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.ailight.jp/blog/kazuk/comments/commentRss/27983.aspx</wfw:commentRss><trackback:ping>http://www.ailight.jp/blog/kazuk/services/trackbacks/27983.aspx</trackback:ping><description>&lt;P&gt;最初にする事&lt;/P&gt;
&lt;P&gt;&lt;A href="http://themechanicalbride.blogspot.com/2009/07/introducing-rx-linq-to-events.html"&gt;http://themechanicalbride.blogspot.com/2009/07/introducing-rx-linq-to-events.html&lt;/A&gt;　の下のほうにURLが出てるんだが&lt;/P&gt;
&lt;P&gt;&lt;A href="http://evain.net/blog/articles/2009/07/30/rebasing-system-reactive-to-the-net-clr"&gt;http://evain.net/blog/articles/2009/07/30/rebasing-system-reactive-to-the-net-clr&lt;/A&gt;　を良く読んで Silverlight 用のランタイム向けになっている System.Reactive.dll にパッチをして通常のCLRで使えるようにする。&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; class SalesEventer&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public event EventHandler&amp;lt;SalesEventArgs&amp;gt; Selled;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void RaiseSelled( string name, int amount )&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Selled( this, new SalesEventArgs() {name = name, amount = amount});&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; internal class SalesEventArgs : EventArgs&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public string name;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public int amount;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/P&gt;
&lt;P&gt;なんかが売れたら売れたよイベントを上げてくれるSalesEventerをこう作った。&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; class Program&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; static void Main(string[] args)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; SalesEventer eventer = new SalesEventer();&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; using (Observable.FromEvent&amp;lt;SalesEventArgs&amp;gt;(eventer, "Selled")&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; .Where(&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; salesEvent =&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; salesEvent.EventArgs.name == "ピザ" &amp;amp;&amp;amp; salesEvent.EventArgs.amount &amp;gt;= 3)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; .Subscribe( s =&amp;gt; Console.WriteLine("ピザ {0}枚とか食いすぎだろ", s.EventArgs.amount)))&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; foreach (int i in Enumerable.Range(1, 5))&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; eventer.RaiseSelled("ピザ", i);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.ReadLine();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/P&gt;
&lt;P&gt;素晴らしい、イベントをフィルタリングしながらハンドルするのがこんなに簡単にだ。&lt;/P&gt;
&lt;P&gt;んで、フィルタリングするだけなら from ... select のLINQクエリ式も書けるので (from ... select ... ).Subscribe( Action ) で書いても良い。&lt;/P&gt;
&lt;P&gt;ちなみに using で使ってるのはSubscribeで IDisposable が帰ってくるから、そして Disposeするとイベントのハンドリングは解除されるって事で IDisposable をちゃんと扱えばイベントのハンドリング制御も全く簡単だ。&lt;/P&gt;
&lt;P&gt;System.Linq.Observable にはなんだか色々と面白そうな物が転がってるのでみんなも試してみてね！&lt;/P&gt;&lt;img src ="http://www.ailight.jp/blog/kazuk/aggbug/27983.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>菊池</dc:creator><title>.NET Reactive Framework</title><link>http://www.ailight.jp/blog/kazuk/archive/2009/08/18/27982.aspx</link><pubDate>Tue, 18 Aug 2009 08:12:00 GMT</pubDate><guid>http://www.ailight.jp/blog/kazuk/archive/2009/08/18/27982.aspx</guid><wfw:comment>http://www.ailight.jp/blog/kazuk/comments/27982.aspx</wfw:comment><comments>http://www.ailight.jp/blog/kazuk/archive/2009/08/18/27982.aspx#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.ailight.jp/blog/kazuk/comments/commentRss/27982.aspx</wfw:commentRss><trackback:ping>http://www.ailight.jp/blog/kazuk/services/trackbacks/27982.aspx</trackback:ping><description>&lt;P&gt;System.Reactive.dll がかなりよさげだ。&lt;/P&gt;
&lt;P&gt;&lt;A href="http://silverlight.codeplex.com/SourceControl/ListDownloadableCommits.aspx"&gt;http://silverlight.codeplex.com/SourceControl/ListDownloadableCommits.aspx&lt;/A&gt;　より Latest Version をダウンロードする。&lt;/P&gt;
&lt;P&gt;Silverlight3/Source/Binaries 配下に System.Reactive.dll があるからぜひ叩いてみよう。&lt;/P&gt;
&lt;P&gt;叩き方は&lt;/P&gt;
&lt;P&gt;&lt;A href="http://themechanicalbride.blogspot.com/2009/07/introducing-rx-linq-to-events.html"&gt;http://themechanicalbride.blogspot.com/2009/07/introducing-rx-linq-to-events.html&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;を参考の事。&lt;/P&gt;
&lt;P&gt;Enjoy!&lt;/P&gt;&lt;img src ="http://www.ailight.jp/blog/kazuk/aggbug/27982.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>菊池</dc:creator><title>構造体型に対するユーザー定義デフォルトコンストラクタ</title><link>http://www.ailight.jp/blog/kazuk/archive/2009/07/26/27964.aspx</link><pubDate>Sun, 26 Jul 2009 04:07:00 GMT</pubDate><guid>http://www.ailight.jp/blog/kazuk/archive/2009/07/26/27964.aspx</guid><wfw:comment>http://www.ailight.jp/blog/kazuk/comments/27964.aspx</wfw:comment><comments>http://www.ailight.jp/blog/kazuk/archive/2009/07/26/27964.aspx#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.ailight.jp/blog/kazuk/comments/commentRss/27964.aspx</wfw:commentRss><trackback:ping>http://www.ailight.jp/blog/kazuk/services/trackbacks/27964.aspx</trackback:ping><description>&lt;P&gt;ネタ元： &lt;A href="http://d.hatena.ne.jp/NyaRuRu/20090726/p1"&gt;ユーザー定義のデフォルトコンストラクタと配列の初期化 - NyaRuRuの日記&lt;/A&gt;&lt;/P&gt;
&lt;BLOCKQUOTE style="MARGIN-RIGHT: 0px" dir=ltr&gt;
&lt;P&gt;.NET アセンブリの仕様としては，構造体にユーザー定義のデフォルトコンストラクタを定義することは可能．ただ，仮に定義したとしても配列の初期化では呼び出されないという点だけで十分に罠過ぎる．&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P dir=ltr&gt;んー、もうちょっと段階分けて書かないと語弊があるかも知れませんですよ。&lt;/P&gt;
&lt;P dir=ltr&gt;CTS(Common Type System)のメタデータ構造的にはどんな型にでもデフォルトコンストラクタを定義する事は可能（パラメーターの無い ctor を書く事ができるという意味で）&lt;/P&gt;
&lt;P dir=ltr&gt;CLI (CLR)的には値型のデフォルトコンストラクタは呼ばれない。&lt;/P&gt;
&lt;P dir=ltr&gt;なんで値型のデフォルトコンストラクタが呼ばれないかというと、呼ぶコードが無いからの一言で済んでしまうんだけど、ILをみてみれば話は速かったりする。&lt;/P&gt;
&lt;P dir=ltr&gt;IL でフィールドを定義する時やローカル変数を定義する時には単純にエリアの確保宣言だけなわけでそこにはデフォルトコンストラクタを呼ぶコードもなければ、参照型では生成時に実行する newObj 的な何らかのオペコードが絡んでいるわけでもない。&lt;/P&gt;
&lt;P dir=ltr&gt;要するに呼べって言われてないから呼ばれない。&lt;/P&gt;
&lt;P dir=ltr&gt;だから値型にデフォルトコンストラクタを定義する意味がない。&lt;/P&gt;
&lt;P dir=ltr&gt;結果としてどんなに頑張ってもコンパイラで暗黙に ctor を呼ぶコードを生成するかあきらめて0初期化を受け入れるかの二択&lt;/P&gt;
&lt;P dir=ltr&gt;んで&lt;/P&gt;
&lt;BLOCKQUOTE style="MARGIN-RIGHT: 0px" dir=ltr&gt;
&lt;P&gt;&lt;SPAN style="mso-ascii-font-family: Calibri; mso-hansi-font-family: Calibri"&gt;&lt;FONT face="ＭＳ Ｐゴシック"&gt;ちなみに値型配列について，ユーザー定義のデフォルトコンストラクタを適用したい場合は，&lt;/FONT&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 'Calibri','sans-serif'" lang=EN-US&gt;&lt;A href="http://msdn.microsoft.com/ja-jp/library/system.array.initialize.aspx" target=_blank&gt;&lt;FONT color=#0000ff&gt;Array.Initialize&lt;/FONT&gt;&lt;/A&gt; &lt;/SPAN&gt;&lt;SPAN style="mso-ascii-font-family: Calibri; mso-hansi-font-family: Calibri"&gt;&lt;FONT face="ＭＳ Ｐゴシック"&gt;という専用メソッドを呼び出してやるか，勝手にこのメソッド呼び出しを挿入してくれる言語とコンパイラが必要．&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P dir=ltr&gt;&lt;SPAN style="mso-ascii-font-family: Calibri; mso-hansi-font-family: Calibri"&gt;&lt;FONT face="ＭＳ Ｐゴシック"&gt;これもまた語弊があって、こういう言語とコンパイラを作ったとするとILレベルでの相互運用性に非常に難のある罠言語ができる&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P dir=ltr&gt;&lt;SPAN style="mso-ascii-font-family: Calibri; mso-hansi-font-family: Calibri"&gt;&lt;FONT face="ＭＳ Ｐゴシック"&gt;なぜなら、CLI上の言語の殆どはここまでの話しの通りに CLI 仕様そのままをユーザーに受け入れさせるべく言語仕様を設定して実装されている。デフォルトコンストラクタを自動的に呼んでくれるコンパイラのはきだしたアセンブリに含まれる値型をインスタンス化する場合にもそのように動く。&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P dir=ltr&gt;&lt;SPAN style="mso-ascii-font-family: Calibri; mso-hansi-font-family: Calibri"&gt;&lt;FONT face="ＭＳ Ｐゴシック"&gt;結果的にそんな言語を作ってデフォルトコンストラクタを頑張って定義しても他言語と相互運用する場合に破綻する可能性が非常に高く、そういう言語とコンパイラ＋相互運用を実現するために既存の.NET言語とのすり合わせをやる何らかのランタイムが必要。要するに ValueTypeのデフォルトコンストラクタでの初期化を実現する VIR (Value type Initialization support Runtime)をDLRみたいに必死こいて実装しないと駄目で、言語とコンパイラを作ってもその中でクローズドな解にしかなりません。&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P dir=ltr&gt;&lt;SPAN style="mso-ascii-font-family: Calibri; mso-hansi-font-family: Calibri"&gt;&lt;FONT face="ＭＳ Ｐゴシック"&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&amp;nbsp;&lt;/P&gt;
&lt;P dir=ltr&gt;&lt;SPAN style="mso-ascii-font-family: Calibri; mso-hansi-font-family: Calibri"&gt;&lt;FONT face="ＭＳ Ｐゴシック"&gt;んで、ILレベルで値型に対してエリア宣言のみでなく何らかのイニシャライズ動作を行う為のop Codeを割り当てなかった理由は知らない、「MSの中の人に聞いてくれ」だけど、仕様文書ではパフォーマンスの為となってるし多分パフォーマンスを強く意識しての事だが本質的にはプリミティブオペレーションが複雑になりすぎるからだと思います。&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P dir=ltr&gt;&lt;SPAN style="mso-ascii-font-family: Calibri; mso-hansi-font-family: Calibri"&gt;&lt;FONT face="ＭＳ Ｐゴシック"&gt;NyaRuRuさんも言及してるけど、配列の初期化を代表格として値型変数がレジスタ割り当てされた時どうすんのよ（一旦メモリにおいてデフォルトコンストラクタ呼んでからレジスタに引き戻す？）とか、ローカル変数にパラメータをそのまま入れる時にローカル変数のデフォルトコンストラクタは呼ぶべき？とか。&lt;/FONT&gt;&lt;/SPAN&gt;&lt;SPAN style="mso-ascii-font-family: Calibri; mso-hansi-font-family: Calibri"&gt;&lt;FONT face="ＭＳ Ｐゴシック"&gt;ローカル変数、フィールド、演算中のテンポラリワーク、色々あるけどすべてにわたって整合性のあるルールとして妥当だったのが「デフォルトの0初期化以外はコード上で明示的に呼ばない限りには行わない」って事かと。&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P dir=ltr&gt;&lt;SPAN style="mso-ascii-font-family: Calibri; mso-hansi-font-family: Calibri"&gt;&lt;FONT face="ＭＳ Ｐゴシック"&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&amp;nbsp;&lt;/P&gt;&lt;img src ="http://www.ailight.jp/blog/kazuk/aggbug/27964.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>菊池</dc:creator><title>Where に埋め込む為に Expression Tree をさらにこねる</title><link>http://www.ailight.jp/blog/kazuk/archive/2009/07/24/27962.aspx</link><pubDate>Fri, 24 Jul 2009 05:28:00 GMT</pubDate><guid>http://www.ailight.jp/blog/kazuk/archive/2009/07/24/27962.aspx</guid><wfw:comment>http://www.ailight.jp/blog/kazuk/comments/27962.aspx</wfw:comment><comments>http://www.ailight.jp/blog/kazuk/archive/2009/07/24/27962.aspx#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.ailight.jp/blog/kazuk/comments/commentRss/27962.aspx</wfw:commentRss><trackback:ping>http://www.ailight.jp/blog/kazuk/services/trackbacks/27962.aspx</trackback:ping><description>&lt;P&gt;LINQ to SQL ではパラメータークエリを作るための &lt;A href="http://msdn.microsoft.com/ja-jp/library/system.data.linq.compiledquery.aspx"&gt;CompiledQuery クラス&lt;/A&gt;がある。&lt;/P&gt;
&lt;P&gt;こいつを使うと LINQ to SQL が SQL 文に変換した結果をキャッシュできるし、パラメータ化したクエリを実行できるのでSQLサーバーサイドでのプランキャッシュも有効に働くため、LINQ to SQLで性能を出す為には利用必須と言いたい機能である。&lt;/P&gt;
&lt;P&gt;この子を使うと言語上で面白い効果が表れる。&lt;/P&gt;
&lt;P&gt;var q = (HogeDataContext db) =&amp;gt; from db.table where ... select ... ;&lt;/P&gt;
&lt;P&gt;通常は上記はコンパイルできない。 ラムダを var に突っ込むなと怒られる。&lt;/P&gt;
&lt;P&gt;var q = CompiledQuery.Compile(&amp;nbsp; (HogeDataContext db )=&amp;gt;from db.table where ... select ... );&lt;/P&gt;
&lt;P&gt;これはコンパイルが通る。なぜなら var は CompiledQuery.Compile の戻り値で示されるFunc型だと決まるし、CompiledQuery.Compile の引数によってラムダは式木である事が強制されてあいまいさが消えるのである。&lt;/P&gt;
&lt;P&gt;さて、このようにメソッド引数を介してあいまい性を消す事ができるという知識とそれをもとにちょっとしたユーティリティメソッドを作らないと匿名型を使ったパラメータクエリの元の式木をいじるのは厄介な問題を抱える事になる。&lt;/P&gt;
&lt;P&gt;public static Expression&amp;lt;Func&amp;lt;TResult&amp;gt;&amp;gt; AsExpression( Expression&amp;lt;Func&amp;lt;TResult&amp;gt;&amp;gt; expression ) { return expression }&lt;BR&gt;public static Expression&amp;lt;Func&amp;lt;T1,TResult&amp;gt;&amp;gt; AsExpression( Expression&amp;lt;Func&amp;lt;T1,TResult&amp;gt;&amp;gt; expression ) { return expression }&lt;BR&gt;&amp;#8230; Func のT4まであるパターンに従って作る&lt;/P&gt;
&lt;P&gt;って感じで渡されたそのものをそのまま返す何もしないメソッドを作ると式木を var で持つのが簡単にできる。&lt;/P&gt;
&lt;P&gt;var q = AsExpression(&amp;nbsp;(HogeDataContext db) =&amp;gt; from db.table where ... select ... );&lt;/P&gt;
&lt;P&gt;AsExpression を作った事により引数型で式木である事が強制されるし、戻り値で式木である事が強制されるのでエラーにならずに式木を匿名型に突っ込む事ができるようになったわけだ。（これができないと匿名型を返す LINQ to SQLクエリの式木をいじるなんて事は不可能だ）&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;んで、 where 部を可変にした LINQ to SQL クエリを作るにはもうひとつの段階が必要で、from &amp;#8230;での LINQ シンタックスから一旦離れる必要がある。なぜなら、式木として組み立てた predicate を呼ぶ方法が無くなってしまうから。&lt;/P&gt;
&lt;P&gt;var pred = AsExpression( (ItemType item) =&amp;gt; item.value!=null );&lt;/P&gt;
&lt;P&gt;として from&amp;nbsp;i in&amp;nbsp;db.Item where pred(i) select i&amp;nbsp;は全くもってコンパイルが通らない。predは変数なのにメソッドの様に使ったと怒られる。&lt;/P&gt;
&lt;P&gt;当然に predは確かに式木なんでそのままでは呼べない。&lt;/P&gt;
&lt;P&gt;これをメソッドチェインで書くとどうなるか。&lt;/P&gt;
&lt;P&gt;var　items = db.Item.Where( pred );&lt;/P&gt;
&lt;P&gt;めでたく items にクエリを格納できるはずだ。&lt;/P&gt;
&lt;P&gt;そして冒頭に出てきた CompiledQuery の問題が再燃する。&lt;/P&gt;
&lt;P&gt;var items = AsExpression( ()=&amp;gt; db.Item.Where(pred) );&lt;BR&gt;Console.WriteLine( items );&lt;/P&gt;
&lt;P&gt;とやると&lt;/P&gt;
&lt;P&gt;() =&amp;gt; value(ConsoleApplication4.Program+&amp;lt;&amp;gt;c__DisplayClass0).Item.Where(value(ConsoleApplication4.Program+&amp;lt;&amp;gt;c__DisplayClass0).pred)&lt;/P&gt;
&lt;P&gt;とか言う表示になるはずだ（仔細は貴方の環境次第だが、value(&amp;#8230;).predとなっているはずだ）、これをCompiledQueryにしようとしても駄目だ、式木は pred を実行時に参照解決して動作するという事になっているのだ。&lt;/P&gt;
&lt;P&gt;もちろん&amp;nbsp;LINQ to SQLで作られたSQL文&amp;nbsp;がSQL Server上で実行されるときに pred がどうなってるかなんて見に来る事はできないしうまくいかない。&lt;/P&gt;
&lt;P&gt;この pred への参照にpred自体を埋め込まなければLINQ to SQL で実行する事はできないしCompiledQueryで使うこともできない。&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public class EmbedLambdaValueVisitor : ExpressionVisitor&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; private LambdaExpression _embedLambda;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public EmbedLambdaValueVisitor(LambdaExpression embedLambda)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _embedLambda = embedLambda;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public Expression EmbedLambda( Expression expression )&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return base.Visit(expression);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; protected override Expression VisitMemberAccess(MemberExpression m)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; var lambda = Expression.Lambda(m);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; var func = lambda.Compile();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (func.Method.ReturnType == _embedLambda.GetType())&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; var value = func.DynamicInvoke();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (value == _embedLambda)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return _embedLambda;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return base.VisitMemberAccess(m);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/P&gt;
&lt;P&gt;上記の ExpressionVisitor 派生はこの問題を解決する。&lt;/P&gt;
&lt;P&gt;EmbedLambdaValueVisitor embed = new EmbedLambdaValueVisitor(&amp;nbsp;pred );&lt;BR&gt;Expression q2 = embed.EmbedLambda(items);&lt;BR&gt;Console.WriteLine( q2 );&lt;/P&gt;
&lt;P&gt;とするとこうなっているはずだ&lt;/P&gt;
&lt;P&gt;() =&amp;gt; value(ConsoleApplication4.Program+&amp;lt;&amp;gt;c__DisplayClass0).Item.Where( (item)=&amp;gt; item.value!=null );&lt;/P&gt;
&lt;P&gt;めでたく pred を参照しているところに pred の内容を埋め込む事ができた。&lt;/P&gt;
&lt;P&gt;VisitMemberAccessの動作が肝だけど、単純に MemberExpression を LambdaのBodyとして作りコンパイル実行して MemberExpressionの結果を取っている（型チェックなどはショートカットに過ぎない）。それが置き換え対象として指示されたLambdaと一致したら MemberExpression の代わりに Lambda を返す事で式木中のMemberExpressionがラムダの実体に置き換えられるという流れだ。&lt;/P&gt;
&lt;P&gt;これを必要なだけ繰り返して MemberExpression をうまくどけてあげれば式木として作ったクエリがLINQ to SQLを介して実行できるようになるだろう。&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;ちなみに from ... select 形式からメソッドチェインの形式への変換は LINQPad でできるよ！って事は某元俺がルールな人から教わった。&lt;/P&gt;&lt;img src ="http://www.ailight.jp/blog/kazuk/aggbug/27962.aspx" width = "1" height = "1" /&gt;</description></item></channel></rss>