GJAX IS UNDER CONSTRUCTION! (※日本語ブログ)

Please wait a minute for GJAX/2008

ホーム 連絡をする 同期する ( RSS 2.0 ) Login
投稿数  171  : 記事  0  : コメント  763  : トラックバック  50

ニュース

今後のスケジュールについて

予定なし

インフォメーション

わんくま同盟メンバ ブログ トップ

ブログタイトル(July 2007~)
GSP.NET GJAX!
【読み方:じーえすぴーどっとねっと/じーじゃっくす】
【サブ:~ A C# programmer dives into ASP.NET! ~】

ASP.NET AJAXと違って、GSP.NET [ghost_shell's (web) pages & .NET]の部分が正式名称、GJAX!の部分が省略形・俗語となっています。

過去のブログタイトル
【表記:ウェブ100】
【読み方:うぇっぶいちまるまる】
【サブ:.Net & Webに てん ぜろ】

書庫

日記カテゴリ

下図の中にあるコードは「yield ステートメントは、匿名メソッドまたはラムダ式の内部では使用できません」というコンパイルエラーが出ます。

http://gshell.wankuma.com/images/2008/4-6/IteratorInFunc1.png

では、Result型のイテレータを返す関数オブジェクト(Func<IEnumerable<Result>>)は作れないのでしょうか?

いえ、あります。
上の図のスタティックコンストラクタの2行目※の部分です。
※テキストの改行ではなくセミコロン基準です。

            iterateFunc = new Func<IEnumerable<int>>(Iterate);

ラムダ式では式(構文)として記述できないだけで、宣言箇所と呼び出し方法の組み合わせによって動作が変わることはありません。
これはデリゲートや匿名メソッドで行った場合も当てはまります。

説明すればするほど、「あぁ、そんなことか。試してみるまでもないじゃん。」と思う人が増えるので、解説が不親切ですがこの辺でやめておきます。
(この記事の最後に貼ってある「この記事に関係する過去の記事」もご覧ください。)

動作するサンプルコードと実行中の様子を以下に示します。

using System;
using System.Collections.Generic;
using System.Threading;
namespace IteratorInFunc
{
    static class Program
    {
        // 逐次処理をする関数オブジェクト
        private static Func<IEnumerable<int>> iterateFunc; 
        // 1 メソッドによる実装
        private static IEnumerable<int> Iterate()
        {
            for (int i = 0; i < 10; ++i)
            {
                Thread.Sleep(1000);
                yield return i;
            }
        }
        // スタティックコンストラクタ
        static Program()
        {
            // 2 【コンパイルエラー】ラムダ式バージョン
            //iterateFunc =
            //    () =>
            //    {
            //        for (int i = 0; i < 10; ++i)
            //        {
            //            Thread.Sleep(1000);
            //            yield return i;
            //        }
            //    };
            iterateFunc = new Func<IEnumerable<int>>(Iterate);
        }
        // メインメソッド
        static void Main(string[] args)
        {
            foreach (var result in iterateFunc())
            {
                DateTime dt = DateTime.Now;
                System.Diagnostics.Debug.WriteLine(String.Format("{0} {1}", result, (dt.Second * 1000 + dt.Millisecond).ToString("D5")));
            }
        }
    }
}

http://gshell.wankuma.com/images/2008/4-6/IteratorInFunc2.png

この記事に関係する過去の記事

【落とし穴】 yield return の間違った使い方 (2007年8月16日)
http://blogs.wankuma.com/gshell/archive/2007/08/16/InvalidUsageOfYieldReturn.aspx


(Posted Date) 19:20

投稿日時 : 2008年4月4日 18:00

コメント

# 言語拡張の功罪 2008/04/04 18:24 Out of Memory
言語拡張の功罪

Post Feedback

タイトル
名前
Url:
コメント: