まさるblog

越後在住子持ちプログラマー奮闘記 - Author:まさる(高野 将、TAKANO Sho)

目次

Blog 利用状況

ニュース

著書

2010/7発売


Web掲載記事

@IT

.NET開発を始めるVB6プログラマーが知るべき9のこと

CodeZine

実例で学ぶASP.NET Webフォーム業務アプリケーション開発のポイント

第1回 3層データバインドを正しく活用しよう(前編)

ブログパーツ


書庫

日記カテゴリ

コミュニティ

夢のあと

夢の競演みたび

夢の競演みたび(アンコール)

の続き。

 

まずは・・・

 

全力でごめんなさい!!<(_ _;)>

 

LINQは遅延実行ってのを、知識として取り込んであったはずなのにすっかり忘れていて、前回おもっくそ間違ったことを書いてしまいました。

すでに何名もの方に突っ込みを食らっていますが、

Where()もループぶん回すので

は間違いで、Where()ではループは回さず、foreachで列挙するときにWhere()で指定した条件でコレクションから値がぶっこ抜かれます。

 

おわびに、ToList()付けたときと付けなかった時の動作を試してみたので、その結果を紹介します。

まず、ToList()無しの場合。

var typedNyans = nyans.Where(x => {
  Console.WriteLine(x.Name);
  return x.Type != "ほげ";
  });

foreach (var nyan in typedNyans)
{
  Console.WriteLine("{0}は{1}", nyan.Name, nyan.Type);
}

image

foreachでの列挙時に条件が評価されていることが見て取れます。

 

んでもって、次はToList()でWhere()の結果を確定させた場合。

var typedNyans = nyans.Where(x => {
  Console.WriteLine(x.Name);
  return x.Type != "ほげ";
  }).ToList();

foreach (var nyan in typedNyans)
{
  Console.WriteLine("{0}は{1}", nyan.Name, nyan.Type);
}

image

まず、ToList()で一回ループが回ってListが作られ、その後foreachの列挙が行われることが見て取れます。

 

なお、ToList()、もしくはToArray()を使うかどうかは、渋木さんがコメントでまとめてくださっていますので、以下に転記しておきます。

Where() が内部で独自にループを回すことはないです。
内部的には yield return で実装されているはずなので、Where() によって返された IEnumerable を foreach などで列挙する時、はじめてループは回ります。(遅延実行)
ただし、Where() が返した IEnumerable を foreach などで列挙すると、毎回 Where() の条件式が評価されるので、それが無駄になる場合はあり得ます。
>ToList()は遅延評価を防ぐために静的な情報にするのが目的では?
その方向が妥当です。
ただし、フィルタして作成したコレクションに項目を追加する予定がないなら、ToArray() でもいいと思います。
てか、「追加する予定がない」「追加してほしくない」ことを強調したい時、僕は ToArray() を使います。

 

みなさん、どうもありがとうございました。勉強になりました。

投稿日時 : 2010年5月27日 22:26

Feedback

No comments posted yet.
タイトル
名前
Url
コメント