あなたの質問に対する答えは、次の 2 つのオプションによって異なります。
- 操作のタイプ: 遅延 (または遅延) および貪欲。遅延操作はすぐには実行されず、コードが linq ソースからデータの具体化を開始するまで延期されます。貪欲な操作は常にすぐに実行されます。
- 遅延操作の例:
.Union
、.Except
、.Where
、 。Select
および他のほとんどの linq 操作
- 貪欲なのは:
.ToList
、.Count
.ToArray
およびデータを具体化するすべての操作
- linq 操作のデータ ソース。Linq to Memory を使用している間、すべての操作 (レイジーと貪欲の両方) がすぐに実行されます。通常、データの外部ソースへのLinqは、実体化中にのみ遅延操作を実行します。
この 2 つのルールを使用すると、linq がどのように動作するかを予測できます。
.Count
.ToList
すぐに実行され、データが具体化されます
- の後
.ToList
、メモリでコレクションを取得し、後続のすべての操作がすぐに実行されます (.Count
もう一度実行されます) 。
- 怠惰または貪欲としてどのよう
.Union
に動作するかは、データ ソースのタイプによって異なります。.Except
メモリの場合は貪欲になり、SQL は遅延します。
LinqPadの例。貪欲なorを使用してマテリアライズする前後に、1つとEnumerable
遅延または延期さ.Where
れた操作があります。.Select
.Count
.ToList
void Main()
{
"get enumerable".Dump();
var samplesEnumerable = GetSamples();
"get count on enumerable #1".Dump();
samplesEnumerable.Count().Dump();
"get enumerable to list #1".Dump();
var list = samplesEnumerable.ToList();
"get count on list #1".Dump();
list.Count().Dump();
"get count on list again #2".Dump();
list.Count().Dump();
"get where/select enumerable #1".Dump();
samplesEnumerable
.Where(sample => { sample.Dump(); return sample.Contains("5"); })
.Select(sample => { sample.Dump(); return sample; })
.Dump();
"get where/select list #1".Dump();
list
.Where(sample => { sample.Dump(); return sample.Contains("5"); })
.Select(sample => { sample.Dump(); return sample; })
.Dump();
}
string[] samples = new [] { "data1", "data2", "data3", "data4", "data5" };
IEnumerable<string> GetSamples()
{
foreach(var sample in samples)
{
sample.Dump();
yield return sample;
}
}
サンプル出力。キーポイント
マテリアライズされていないデータでは、すべて.Count
の.List
データが何度も何度もデータを取得しています
get count on enumerable #1
get where/select enumerable #1
データを実体化した後、列挙型は取得されなくなります
get enumerable to list #1
get count on list #1
get count on list again #2
get where/select list #1
出力:
get enumerable
get count on enumerable #1
data1
data2
data3
data4
data5
5
get enumerable to list #1
data1
data2
data3
data4
data5
get count on list #1
5
get count on list again #2
5
get where/select enumerable #1
data1
data1
data2
data2
data3
data3
data4
data4
data5
data5
data5
data5
get where/select list #1
data1
data2
data3
data4
data5
data5
data5