HIRASE CONNECTION WK

programming collection

目次

Blog 利用状況

ニュース

あわせて読みたいブログパーツ

書庫

日記カテゴリ

Link Collection

[C#] クロージャ?

クロージャってのをよくわからず次のコードを「クロージャだと思って」コーディング。

using System;

internal class PetitClosure
{
    private static void Main()
    {
        Func<int> f = CreateFunc();
        Console.WriteLine(f());
        Console.WriteLine(f());
        Console.WriteLine(f());
        Console.WriteLine(f());
    }

    private static Func<int> CreateFunc()
    {
        int i = 0;
        return delegate
            {
                i = i + 1;
                return i;
            };
    }
}

結果は、「1,2,3,4」・・・・・。えぇ・・・! すご。

ポイント

ポイントは、CreateFunc関数で作られた関数 f を作ったときには、関数 f の戻り値が決定せず、関数 f が呼ばれるたびに CreateFunc関数内のスコープにある変数 i をインクリメントして戻してくれるってことですね。

うー。まだまだ知らないことばっかだ。

投稿日時 : 2008年3月16日 22:12

コメントを追加

# re: [C#] クロージャ? 2008/03/16 22:36 myugaru

こんばんわー。確かにクロージャっぽいですよねっ。
ちなみにラムダ式を使うと便利ですぉ。
private static Func<int> CreateFunc()
{
 int j = 0;
 return () => ++j;
}

それと余談かもしれませんが。
CreateFunc()内でreturnの前にjの値変えるとf()内にも影響与えます。
何言ってるかと言うと
private static Func<int> CreateFunc()
{
 int j = 0;
 Func<int> f = () => ++j; // ★ここで1回仮に代入しとく
j = 8; // return前にj変えてみる
return f;
}
こうするとfは★の位置で0から返すFunc<int>に確定されている様にみえますが、
実際にはf()が8から戻し始めます。
jのスコープ内だから当然といえば当然ですが。
このj=8の位置がすごく下のほうにあったりすると結構直し辛いバグになったりします。
デリゲート&ローカル変数を返すパターンはスコープの動作をきちんと理解して知っておかないと使うのは難しいです。

# re: [C#] クロージャ? 2008/03/17 0:27 T.Hirase

こんばんわです。myugaruさま。
コメントありがとうございます。

>ラムダ式
おぉ・・、こんなところで使い道が。。ありがとうございます。
# これを思いつけない自分は、まだまだ伸び盛りなんだ・・、きっと。

>直し辛いバグ
確かに。
ちょっと長めのローカル関数とか返すとバグを誘発しそうです。
使うときは短めの関数あるいは、それを定義している関数に
依存しないようなときだけ返すほうが無難そうですね。

あと、Disposeされちゃったコンポーネントにアクセスしたら酷い目に合いそうですね。
きっと、.NET Frameworkのバグだと信じてしまいそうです。
こんなの↓
private static Func<Color> CreateFunc()
{
using (Bitmap image = Bitmap.FromFile(@"picture.bmp") as Bitmap)
{
int x = 0, y = 0;
return () => image.GetPixel(x++, y++);
}
}

# re: [C#] クロージャ? 2008/03/17 7:57 myugaru

あれ、なんだか私のコードがjになってました。
日本人(japanese)だからjが好きっって事でw
return () => image.GetPixel(x++, y++);
うんうんうん。
こういう事に現実にハマル人っていうのは大抵使い慣れてないのが問題ですにゃ。

コーディングの効率上げようとして裏技使いすぎると
デバッグで効率が落ちる典型的ダメパターンですぞっ(焦
とりあえずいくら言語仕様がどんどん進化したとしても、
実務では多数決とれば素直素直なコードがいつまでも喜ばれますにょ。
遊びならどんどん深みにハマルのは言語を深く知るためにもOKですね。
(遊びすぎの図→http://d.hatena.ne.jp/myugaru/20071224/1198568665

# re: [C#] クロージャ? 2008/03/17 8:24 T.Hirase

>jになってました
お気になさらず。瑣末なことです。

>使い慣れてないのが問題
ですよね。
使いどころがわからないうちは、無理やり使わないのがコツかと思います。
自然な流れに思考を任せ、より短く、より直感的なコードで書くことが重要だと思います。
クラスに慣れていない人が変なクラスを書くのも同じですね。

それにしても遊びだすと止まらないですなー。

# re: [C#] クロージャ? 2008/03/18 3:10 myugaru

すみません、ちょっとHiraseさんとの距離感が掴めず語尾がフランクすぎたと反省しています。
こんな私ですが今本人的にはコレまでの人生でもっとも一生懸命にゲームなるものを生み出すべくプログラミングをがんばっています。
なんていうことをゲームを仕事とされている人に言うのは本当に大ばか者だとわかっています。
でも色々な人からアドバイスなどぜひともほしいので、特にお仕事でされている方から見た意見なんてお金出してでもほしいくらいです(焦焦
なので・・・その・・・私がもし何か作品を作り出したりしちゃったときにはぜひとも何か突っ込みもらえると嬉しいです。
あ、明日とかあさってとかそういうレベルじゃ全然何も作れて居ません><。
たぶん早くても数ヶ月先とかになる感じかもです(遠いです・・・泣
あと・・私は細く長く色んな人とコミュニティを作って生きたい派です。
ではでは勝手なこと書き散らして退散します・・・。

P.S.フレッシュ平瀬さんのページはなんだかとても心が癒されました。

# re: [C#] クロージャ? 2008/03/18 10:09 T.Hirase

>語尾がフランクすぎた
もう、全然そんなことないですよ。
私なんて、まだ社会人2年目(4月から3年目)のペーペーですし。
ゲーム業界といっても、ミドルウェアですし。

>P.S.フレッシュ平瀬さんのページはなんだかとても心が癒されました。
最近、あちらのページを更新してないのがバレる・・。
わんくまも、あちらも両方とも頑張っていきたいです。

ともあれ、myugaruさん、今後ともよろしくお願いします。

タイトル  
名前  
URL
コメント