28
16

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

.NET 8でLINQに追加されたメソッド

Posted at

概要

2023年11月に.NET 8C# 12がリリースされました。

この投稿では、.NET 8でLINQに追加された「ToDictionaryの複数のオーバーロード」について紹介します。

昨年リリースの「.NET 7」で追加されたメソッドは、こちらをどうぞ!

一昨年リリースの「.NET 6」で追加されたメソッドはこちらをどうぞ!

ToDictionaryメソッドとは?

ToDictionaryメソッドは、次のコードのようにIEnumerable<T>から、Dictionary<TKey, TSource>を作成するメソッドです。

Skillレコード
public readonly record struct Skill(int Id, string Name);
ToDictionaryの利用例
List<Skill> skills = [
    new Skill(
        Id: 0,
        Name: "ファイアー"
    ),
    new Skill(
        Id: 1,
        Name: "エルファイアー"
    ),
    new Skill(
        Id: 2,
        Name: "サンダー"
    ),
    new Skill(
        Id: 3,
        Name: "サンダーストーム"
    ),
    new Skill(
        Id: 4,
        Name: "エイルカリバー"
    )
];

var skillNameDictionary = skills.ToDictionary(it => it.Id, it => it.Name);

Console.WriteLine(skillNameDictionary[0]); // ファイアー
Console.WriteLine(skillNameDictionary[1]); // エルファイアー

.NET 7までは、次の4種のオーバーロードがありました。

一見複雑そうですが、次の組み合わせで4パターンとなります。

  • キーセレクターのみ(Func<TSource,TKey>)を引数に取る or キーセレクター(Func<TSource,TKey>)とバリューセレクター(Func<TSource,TElement>)両方を引数に取る
  • IEqualityComparer<TKey>を引数に取る or 引数に取らない

既存のオーバーロードは、すべてIEnumerable<TSource>の拡張メソッドであることに注目してください。

新たにToDictionaryメソッドに追加されたオーバーロードは?

新たにToDictionaryメソッドに追加されたオーバーロードは、次の4個です。

既存のオーバーロードは、すべてIEnumerable<TSource>の拡張メソッドでした。新たに追加されたオーバーロードは

IEnumerable<KeyValuePair<TKey,TValue>>

または

IEnumerable<ValueTuple<TKey,TValue>>

の拡張メソッドです。

次の組み合わせで4パターンとなります。

  • IEnumerable<KeyValuePair<TKey,TValue>>の拡張メソッド or IEnumerable<ValueTuple<TKey,TValue>>の拡張メソッド
  • IEqualityComparerを引数に取る or IEqualityComparerを引数に取らない

どんなふうに使う?何が嬉しい?

新たに加わったオーバーロードにより、IEnumerable<KeyValuePair<TKey,TValue>>またはIEnumerable<ValueTuple<TKey,TValue>>に対して、
ToDictionary(it => it.Key, it => it.Value)」のような記述を、
ToDictionary()」と簡潔に記述できるようになります。

例えば、Dictionary<TKey, TSource>は、IEnumerable<KeyValuePair<TKey,TValue>>を実装しています。そのため、次のようにDictionary<TKey, TSource>をフィルタリングして、Dictionary<TKey, TSource>を再構成するコードが簡潔にかけます。

ToDictionaryの利用例
// TODO もっと.NET 8っぽく書く
List<Skill> skills = [
    new Skill(
        Id: 0,
        Name: "ファイアー"
    ),
    /* 略 */
];

var skillNameDictionary = skills.ToDictionary(it => it.Id, it => it.Name);

var onlyFireSkillNameDictonary = skillNameDictionary
    .Where(it => it.Value.Name.Contains("ファイアー"))
    .ToDictionary(); // .NET 7までは、「.ToDictionary(it => it.Key, it => it.Value)」ってやってた

なお、新たに追加されたオーバーロードも既存のオーバーロードと同様、キーの重複に対してArgumentExceptionをスローすることに注意してください

まとめ

.NET 8でLINQに追加された「ToDictionaryの複数のオーバーロード」について紹介しました。

新たに加わったオーバーロードにより、IEnumerable<KeyValuePair<TKey,TValue>>またはIEnumerable<ValueTuple<TKey,TValue>>で、「ToDictionary(it => it.Key, it => it.Value)」と記述をしていた箇所を「ToDictionary()」と簡潔に記述できるよになりました。

個人的には、.NET 8でのLINQの追加は、「そんなに自分が活用する機会は多くないかもな〜」とも思いますが、今後の進化も楽しみです。

リンク

28
16
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
28
16

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?