C#で即時関数パターン

即時関数パターンとは

即時関数パターンとは、関数をその場で作りその場で使うコーディングパターンのことです。

主にJavaScriptで使用される用語で、メソッド内でスコープを狭める目的でも使うことがあります。

[javascript] var hoge= (function () {
var x = 1;
var y = 2;
return x + y;
};
}());
[/javascript]

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();
    }
};

こんな感じの文法が欲しいです。