Up to date

This page is up to date for Godot 4.2. If you still find outdated information, please open an issue.

C# 集合

.NET 基类库包含多种集合类型,可以用来存储和操作数据。Godot 也提供了一些集合类型,它们与引擎的其他部分紧密集成。

选择一种集合

.NET 集合 和 Godot 集合的主要区别是 .NET 集合是用 C# 实现的,而 Godot 集合是用 C++ 实现的,Godot C# API 是对它的一个封装,这是一个重要的区别,因为它意味着对 Godot 集合的每一个操作都需要进行封送(marshaling),这可能会非常耗费资源,尤其是在循环中。

由于性能影响,仅在绝对必要时(例如与 Godot API 交互)才建议使用 Godot 集合。Godot 只能理解其自己的集合类型,因此在与引擎交互时需要使用它们。

如果你有一组元素,不需要传递给 Godot API,使用 .NET 集合会更高效。

小技巧

.NET 集合和 Godot 集合之间也可以进行转换。Godot 集合包含从通用 .NET 集合接口复制元素的构造函数,而且 Godot 集合可以与 LINQ ToListToArrayToDictionary 方法一起使用。但要注意,这种转换需要对集合中的每个元素进行封送并将其复制到新集合中,因此可能会很耗费资源。

尽管如此,Godot 集合经过优化,试图避免不必要的封送,因此如 SortReverse 等方法通过单个交互调用实现,无需封送每个元素。要注意那些接受像 LINQ 这样的集合接口的通用 API,因为每个方法都需要遍历集合,因此需要封送每个元素。尽量在可能的情况下使用 Godot 集合的实例方法。

为了选择在不同情况下使用哪种集合类型,请考虑以下问题:

  • 你的集合是否需要与 Godot 引擎交互?(例如:导出属性的类型,调用 Godot 方法)。

  • 你是否需要一个 Godot 集合,用来表示一个列表或顺序的数据集?

    • Godot 数组 与 C# 集合 List<T> 类似。

    • Godot 紧缩数组 是更高效的内存数组,在 C# 中使用一个支持 System.Array 的类型。

  • 你需一个 Godot 集合将一组键映射到一组值吗?

    • Godot 字典 存储键值对,并通过其关联的键轻松访问值。

Godot 集合

紧缩数组

Godot 中的紧缩数组以指定类型的数组形式实现,这样就能够更加紧实,每个元素都只有各自类型的大小,而不是 Variant 的大小。

在 C# 中,紧缩数组由 System.Array 代替:

GDScript

C#

PackedInt32Array

int[]

PackedInt64Array

long[]

PackedByteArray

byte[]

PackedFloat32Array

float[]

PackedFloat64Array

double[]

PackedStringArray

string[]

PackedColorArray

Color[]

PackedVector2Array

Vector2[]

PackedVector3Array

Vector3[]

其他 C# 数组在 Godot C# API 中不受支持,因为没有等效的紧缩数组。请查看 Variant 以获取所有兼容类型的列表。

数组

Godot 数组被实现为一个包含多个任意类型元素的 Variant 数组。在 C# 中,对应的类型是 Godot.Collections.Array

泛型 Godot.Collections.Array<T> 类型允许将元素类型限制为 Variant 兼容 类型。

一个未指定类型的 Godot.Collections.Array 可以使用 Godot.Collections.Array<T>(Godot.Collections.Array) 构造函数转换为一个指定类型的数组。

备注

尽管名字如此,Godot 数组与 C# 集合 List<T> 更相似,而不是 System.Array 。它们的大小不固定,随着集合中添加/删除元素而增长或缩小。

Godot Array 方法列表及其在 C# 中的对应:

GDScript

C#

all

System.Linq.Enumerable.All

any

System.Linq.Enumerable.Any

append

Add

append_array

AddRange

assign

Clear 和 AddRange

back

Array[^1]System.Linq.Enumerable.LastSystem.Linq.Enumerable.LastOrDefault

bsearch

BinarySearch

bsearch_custom

N/A

clear

Clear

count

System.Linq.Enumerable.Count

duplicate

Duplicate

erase

Remove

fill

Fill

filter

使用 System.Linq.Enumerable.Where

find

IndexOf

front

Array[0]System.Linq.Enumerable.FirstSystem.Linq.Enumerable.FirstOrDefault

get_typed_builtin

N/A

get_typed_class_name

N/A

get_typed_script

N/A

has

Contains

hash

GD.Hash

insert

Insert

is_empty

使用 Count == 0

is_read_only

IsReadOnly

is_same_typed

N/A

is_typed

N/A

make_read_only

MakeReadOnly

map

System.Linq.Enumerable.Select

max

Max

min

Min

pick_random

PickRandom(请考虑用 System.Random

pop_at

Array[i]RemoveAt(i)

pop_back

Array[^1]RemoveAt(Count - 1)

pop_front

Array[0]RemoveAt(0)

push_back

Insert(Count, item)

push_front

Insert(0, item)

reduce

System.Linq.Enumerable.Aggregate

remove_at

RemoveAt

resize

Resize

reverse

Reverse

rfind

LastIndexOf

shuffle

Shuffle

size

Count

slice

Slice

sort

Sort

sort_custom

System.Linq.Enumerable.OrderBy

操作符 !=

!RecursiveEqual

操作符 +

操作符 +

操作符 <

N/A

操作符 <=

N/A

操作符 ==

RecursiveEqual

操作符 >

N/A

操作符 >=

N/A

操作符 []

Array[int] 索引器

字典

Godot 字典是用 Variant 类型的键和值实现的。在 C# 中,对应的类型是 Godot.Collections.Dictionary

泛型 Godot.Collections.Dictionary<TKey, TValue> 类型允许将键和值的类型限制为 Variant 兼容 类型。

一个无类型的 Godot.Collections.Dictionary 可以用 Godot.Collections.Dictionary<TKey, TValue>(Godot.Collections.Dictionary) 构造函数转换为一个有类型的字典。

小技巧

如果你需要一个字典,其中键是有类型的,但值没有类型,那么使用 Variant 作为有类型字典的 TValue 泛型参数。

// The keys must be string, but the values can be any Variant-compatible type.
var dictionary = new Godot.Collections.Dictionary<string, Variant>();

Godot Dictionary 的方法列表及其在 C# 中的对应方法:

GDScript

C#

clear

Clear

duplicate

Duplicate

erase

Remove

find_key

N/A

get

Dictionary[Variant] 索引器 或 TryGetValue

has

ContainsKey

has_all

N/A

hash

GD.Hash

is_empty

使用 Count == 0

is_read_only

IsReadOnly

keys

Keys

make_read_only

MakeReadOnly

merge

Merge

size

Count

values

Values

操作符 !=

!RecursiveEqual

操作符 ==

RecursiveEqual

操作符 []

Dictionary[Variant] 索引器,Add 或 TryGetValue