17

Enumerable.GroupByおよびQueryable.GroupBy拡張機能には 8 つのオーバーロードがあります。それらのうちの 2 つ (の場合Enumerable.GroupBy) は次のとおりです。

// (a)
IEnumerable<TResult> GroupBy<TSource, TKey, TResult>(
    this IEnumerable<TSource> source,
    Func<TSource, TKey> keySelector,
    Func<TKey, IEnumerable<TSource>, TResult> resultSelector);

// (b)
IEnumerable<TResult> GroupBy<TSource, TKey, TElement, TResult>(
    this IEnumerable<TSource> source,
    Func<TSource, TKey> keySelector,
    Func<TSource, TElement> elementSelector,
    Func<TKey, IEnumerable<TElement>, TResult> resultSelector);

Queryable.GroupBy同じように、Expression<Func<...代わりに を使用Func<...

(b)追加elementSelectorの as パラメータがあります。

MSDN には過負荷 (a) の例と過負荷 (b) の例があります。どちらも同じサンプル ソース コレクションで動作します。

List<Pet> petsList = new List<Pet>
{
    new Pet { Name="Barley", Age=8.3 },
    new Pet { Name="Boots", Age=4.9 },
    new Pet { Name="Whiskers", Age=1.5 },
    new Pet { Name="Daisy", Age=4.3 }
};

例 (a) では、次のクエリを使用します。

var query = petsList.GroupBy(
    pet => Math.Floor(pet.Age), // keySelector
    (age, pets) => new          // resultSelector
    {
        Key = age,
        Count = pets.Count(),
        Min = pets.Min(pet => pet.Age),
        Max = pets.Max(pet => pet.Age)
    });

例 (b) では、次のクエリを使用します。

var query = petsList.GroupBy(
    pet => Math.Floor(pet.Age), // keySelector
    pet => pet.Age,             // elementSelector
    (baseAge, ages) => new      // resultSelector
    {
        Key = baseAge,
        Count = ages.Count(),
        Min = ages.Min(),
        Max = ages.Max()
    });

両方のクエリの結果はまったく同じです。

質問 1: だけでは表現できず、resultSelector本当に が必要なクエリはありelementSelectorますか? それとも、2 つのオーバーロードの機能は常に同等であり、どちらを使用するかは単なる好みの問題ですか?

質問 2: LINQ クエリ構文を使用する場合、2 つの異なるオーバーロードに対応するものはありますか?

(Queryable.GroupBy余談ですが、Entity Framework を使用する場合、両方のオーバーロードはまったく同じ SQL に変換されますか?)

4

1 に答える 1