コレクションビルダー
カスタム型でコレクション式をサポートします。
「コレクションビルダー」はCoddyKit上の無料C# Academyレッスンです。 これはレッスン4/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはC# Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 C# Academyコースには全4レッスンが含まれています。
コレクション式でのカスタム型
コレクション式は組み込み型に限定されません。[CollectionBuilder] 属性を使うと、独自の型も [...] 構文から作成できます。
CollectionBuilder 属性
コレクション型に [CollectionBuilder(typeof(Factory), "Create")] を適用します。これにより、コンパイラがインスタンスの構築に呼び出す静的ファクトリーメソッドを指定します。
ビルダーメソッドのシグネチャ
ビルダーメソッドは static で、単一の ReadOnlySpan<T> パラメーターを受け取り、コレクション型を返す必要があります。コンパイラは要素をスパンとして渡します。
最小限のカスタムコレクション
これは、ビルダーを介したコレクション式による生成に対応する、小さなイミュータブルコレクションの例です。
using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
[CollectionBuilder(typeof(IntBagBuilder), "Create")]
class IntBag : IEnumerable<int> {
private readonly int[] items;
public IntBag(ReadOnlySpan<int> data) => items = data.ToArray();
public IEnumerator<int> GetEnumerator() => ((IEnumerable<int>)items).GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => items.GetEnumerator();
}
static class IntBagBuilder {
public static IntBag Create(ReadOnlySpan<int> data) => new IntBag(data);
}
IntBag bag = [1, 2, 3];
foreach (int n in bag) Console.Write(n + " "); // 1 2 3
Console.WriteLine();なぜ ReadOnlySpan なのか
スパンパラメーターを使うと、コンパイラは中間的な割り当てなしで要素を渡せます。ビルダーは、必要なストレージに要素をコピーします。
IEnumerable の実装が必要
コンパイラが要素型を把握し、使用方法を検証できるように、コレクション型は IEnumerable<T>(スパンの要素型と一致)を実装する必要があります。
ジェネリックビルダー
ビルダーはジェネリックにできるため、MyCollection<T> をサポートできます。ビルダーメソッドは ReadOnlySpan<T> を受け取り、MyCollection<T> を返します。
using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
[CollectionBuilder(typeof(BoxBuilder), "Create")]
class Box<T> : IEnumerable<T> {
private readonly T[] items;
public Box(ReadOnlySpan<T> d) => items = d.ToArray();
public IEnumerator<T> GetEnumerator() => ((IEnumerable<T>)items).GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => items.GetEnumerator();
}
static class BoxBuilder {
public static Box<T> Create<T>(ReadOnlySpan<T> d) => new Box<T>(d);
}
Box<string> b = ["x", "y"];
foreach (var s in b) Console.Write(s + " "); // x y
Console.WriteLine();イミュータブルコレクションの利点
ビルダーは、ImmutableArray<T> などの .NET のイミュータブルコレクションがコレクション式をサポートするための仕組みです。ビルダーはスパンから変更不可能なインスタンスを構築します。
using System;
using System.Collections.Immutable;
ImmutableArray<int> nums = [1, 2, 3];
Console.WriteLine(nums.Length); // 3スプレッドも使用可能
型にビルダーを用意すると、そのコレクション式内でスプレッドも自動的に使用できます。コンパイラが引き続き要素を1つのスパンとして生成するためです。
using System;
using System.Collections.Immutable;
ImmutableArray<int> a = [1, 2];
ImmutableArray<int> all = [..a, 3, 4];
Console.WriteLine(all.Length); // 4ビルダーを追加するタイミング
カスタムコレクションを提供し、呼び出し側に簡潔な [...] 構文を使ってもらいたい場合は、[CollectionBuilder] を追加します。特に、イミュータブルなコンテナーや特殊用途のコンテナーで有効です。
総合例
ビルダーは、属性、IEnumerable<T> 型、静的な Create(ReadOnlySpan<T>) メソッドという3つの要素で構成されます。これらを用意すると、独自の型がコレクション式の正式なターゲットになります。
理解度チェック
コレクションビルダーの要件を確認しましょう。
まとめ
カスタム型でコレクション式をサポートする方法を学びました。
- 型に
[CollectionBuilder(typeof(Factory), "Create")]を適用します。 - ファクトリーは
ReadOnlySpan<T>を受け取るstaticメソッドです。 - 型は
IEnumerable<T>を実装する必要があります。 - これが、
ImmutableArray<T>が[...]を受け入れる仕組みです。
よくある質問
「コレクションビルダー」レッスンは無料ですか?
はい。「コレクションビルダー」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、C# Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 C# Academyコースには全4レッスンが含まれています。
「コレクションビルダー」で何を学びますか?
カスタム型でコレクション式をサポートします。 ブラウザで直接実行するハンズオンコードでC# Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
C# Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのC# Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン4/4です。
「コレクションビルダー」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このC# Academyレッスンでコードを書いて実行できますか?
はい。すべてのC# Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- コレクション式の構文
- Spread要素
- コレクションのターゲット型指定
- コレクションビルダー