即時関数パターンとは
即時関数パターンとは、関数をその場で作りその場で使うコーディングパターンのことです。
主にJavaScriptで使用される用語で、メソッド内でスコープを狭める目的でも使うことがあります。
var hoge= (function () { var x = 1; var y = 2; return x + y; }; }());
JavaScriptでは任意のスコープを作る方法が即時関数 パターンしかなく、裏技的なテクニックとして紹介されていました。
C#で即時関数パターン
C#では、{}で囲うとスコープを作れるため、即時関数パターンを使う場面は一見なさそうです。
しかし、こんな処理を書くことはありませんでしょうか。
MyClass hoge = null; { try{ hoge = MyMethod(); } catch{ fuga.Dispose(); throw new MyException(); } }
try内でhogeを宣言すると、tryを抜けた箇所で使えなくなってしまいます。
そのためhoge外側でnull宣言するのですが、あまり見栄えがよくありません。
これを即時関数パターンで書くと
var hoge = new Func<MyClass>( () => { try{ return MyMethod(); } catch{ fuga.Dispose(); throw new MyException(); } })();
と書くことができます。
「new Func<MyClass>(」で MyClassを返す匿名関数をつくり、
「() =>{…}」でその関数の内容を書いています。
メリット
hoge にnullを代入しなくて済みますし、 型推論も効いてvarを使うこともできます。
また、コピペした場合に修正が容易で、修正時のバグの混入を防ぐことができるのも特長です。
前者のコーディングだと、コピペ先の try内の hogeを書き換えるのを忘れても警告もなにも出ませんが、
このコーディングならそもそも修正が必要ありません。
デメリット
おそらくほんの少しパフォーマンスが落ちます。ループ内では使わないほうがいいかもしれません。
また、最後の行の()を抜かすと Func<MyClass>型になってしまうのも注意点です。
おまけ
//動きません var hoge =<MyClass>{ try{ return MyMethod(); } catch{ fuga.Dispose(); throw new MyException(); } };
こんな感じの文法が欲しいです。