集合构建器
让自定义类型支持集合表达式。
集合构建器 是 CoddyKit 上的免费 C# Academy 课时。 这是第 4 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 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<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();不可变集合的优势
构建器是 .NET 不可变集合(例如 ImmutableArray<T>)支持集合表达式的方式。构建器会根据跨度构造冻结的实例。
using System;
using System.Collections.Immutable;
ImmutableArray<int> nums = [1, 2, 3];
Console.WriteLine(nums.Length); // 3展开元素同样适用
类型拥有构建器后,其集合表达式中会自动支持展开元素,因为编译器仍然会生成一个包含所有元素的跨度。
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>) 方法。有了这些,您的类型就能作为一等集合表达式目标。
快速检查
确认集合构建器的要求。
回顾
您学习了自定义类型如何支持集合表达式。
- 将
[CollectionBuilder(typeof(Factory), "Create")]应用于该类型。 - 工厂是一个接受
ReadOnlySpan<T>的static方法。 - 该类型必须实现
IEnumerable<T>。 ImmutableArray<T>正是通过这种方式接受[...]的。
常见问题解答
「集合构建器」课时是免费的吗?
是的 — 「集合构建器」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 C# Academy 课程的其余内容,请升级到 CoddyKit PRO。 C# Academy 课程共包含 4 节课。
「集合构建器」这节课中我会学到什么?
让自定义类型支持集合表达式。 你通过在浏览器中直接运行的动手代码来练习 C# Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 C# Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 C# Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 4 节课,共 4 节。
「集合构建器」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 C# Academy 课中编写并运行代码吗?
能。每节 C# Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。