0Pricing
C# Academy · レッスン

コレクションビルダー

カスタム型でコレクション式をサポートします。

「コレクションビルダー」は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フィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. コレクション式の構文
  2. Spread要素
  3. コレクションのターゲット型指定
  4. コレクションビルダー
← C# Academyに戻る