Attention: Here be dragons
This is the latest
(unstable) version of this documentation, which may document features
not available in or compatible with released stable versions of Godot.
Checking the stable version of the documentation...
C# Variant
对于 Variant 的详细解释,请参阅 Variant 文档页面。
Godot.Variant
用于表示 Godot 的原生 Variant 类型。任何 Variant 兼容类型 都可以和它进行转换。我们建议仅在与无类型的引擎 API 交互时使用 Godot.Variant
。尽可能利用 C# 的类型安全性。
将 Variant 兼容的 C# 类型转换为 Godot.Variant
可以使用隐式转换。也有 CreateFrom
方法重载和泛型 Variant.From<T>
方法。只有语法不同:行为是相同的。
int x = 42;
Variant numberVariant = x;
Variant helloVariant = "Hello, World!";
Variant numberVariant2 = Variant.CreateFrom(x);
Variant numberVariant3 = Variant.From(x);
隐式转换为 Godot.Variant
使得将变体作为方法参数传递非常方便。例如,tween_property 的第三个参数指定了补间的最终颜色,是一个 Godot.Variant
。
Tween tween = CreateTween();
tween.TweenProperty(GetNode("Sprite"), "modulate", Colors.Red, 1.0f);
从 Godot.Variant
转换为 C# 类型可以使用显式转换。还有 Variant.As{TYPE}
方法和泛型 Variant.As<T>
方法。所有这些的行为是相同的。
int number = (int)numberVariant;
string hello = (string)helloVariant;
int number2 = numberVariant.As<int>();
int number3 = numberVariant.AsInt32();
备注
Variant.As{TYPE}
方法通常以 C# 类型命名( Int32
),而不是 C# 关键字( int
)。
如果 Variant 类型与转换目标类型不匹配,则结果会根据源值和目标值而有所不同。
转换可能会检查该值并返回目标类型的类似但可能出乎意料的值。例如,字符串
"42a"
可能会被转换为整数42
。可能会返回目标类型的默认值。
可能会返回一个空数组。
可能会引发一个异常。
转换为正确的类型可以避免复杂的行为,因此应优先考虑。
Variant.Obj
属性返回一个 C# object
,其中包含任何变体的正确值。当变体的类型完全未知时,这可能很有用。但是,如果可能,最好使用更具体的转换。Variant.Obj
会关于 Variant.VariantType
执行一个 switch
,这可能不是必需的。此外,如果结果是值类型,则会对其进行装箱。
例如,如果 Variant.As<MyNode>()
引发一个无效转换异常的可能性是不可接受的,请考虑改用 Variant.As<GodotObject>() is MyNode n
类型模式。
备注
由于 C# 中的 Variant 类型是一个结构体,它不能为 null。要创建一个 “null” Variant,请使用 default
关键字或 Godot.Variant
无参数构造函数。
Variant 兼容类型
Variant 兼容类型可以与 Godot.Variant
相互转换。以下 C# 类型与 Variant 兼容:
除了
decimal
、nint
和nuint
之外,所有的 内置值类型 。String
。从 GodotObject 派生的类。
在
Godot.Collections
命名空间中定义的集合类型。
Variant 类型的完整列表及其对应的 C# 类型:
Variant.Type |
C# 类型 |
---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
警告
Godot 在 Variant 中使用 64 位的整数和浮点数。较小的整数和浮点数类型,如 int
,short
和 float
,也是支持的,因为它们可以容纳在更大的类型中。请注意,执行转换时,使用错误的类型可能会导致潜在的精度损失。
警告
枚举类型由于其底层类型是整数类型,因此都与 Godot.Variant
兼容。但是,隐式转换不存在,枚举类型必须在转换为/从 Godot.Variant
之前手动转换为其底层的整数类型,或者使用通用的 Variant.As<T>
和 Variant.From<T>
方法来转换它们。
enum MyEnum { A, B, C }
Variant variant1 = (int)MyEnum.A;
MyEnum enum1 = (MyEnum)(int)variant1;
Variant variant2 = Variant.From(MyEnum.A);
MyEnum enum2 = variant2.As<MyEnum>();
在泛型上下文中使用 Variant
在使用泛型时,你可能希望限制泛型 T
类型仅为 Variant 兼容类型之一。这可以通过使用 [MustBeVariant]
特性来实现。
public void MethodThatOnlySupportsVariants<[MustBeVariant] T>(T onlyVariant)
{
// Do something with the Variant-compatible value.
}
结合泛型 Variant.From<T>
可以让你从一个泛型 T
类型的实例中获取一个 Godot.Variant
的实例。然后它可以用在任何只支持 Godot.Variant
结构体的 API 中。
public void Method1<[MustBeVariant] T>(T variantCompatible)
{
Variant variant = Variant.From(variantCompatible);
Method2(variant);
}
public void Method2(Variant variant)
{
// Do something with variant.
}
为了调用一个带有泛型参数的方法,该参数用 [MustBeVariant]
特性标注,值必须是 Variant 兼容类型或者带有 [MustBeVariant]
特性标注的泛型 T
类型。
public class ObjectDerivedClass : GodotObject { }
public class NonObjectDerivedClass { }
public void Main<[MustBeVariant] T1, T2>(T1 someGeneric1, T2 someGeneric2)
{
MyMethod(42); // Works because `int` is a Variant-compatible type.
MyMethod(new ObjectDerivedClass()); // Works because any type that derives from `GodotObject` is a Variant-compatible type.
MyMethod(new NonObjectDerivedClass()); // Does NOT work because the type is not Variant-compatible.
MyMethod(someGeneric1); // Works because `T1` is annotated with the `[MustBeVariant]` attribute.
MyMethod(someGeneric2); // Does NOT work because `T2` is NOT annotated with the `[MustBeVariant]` attribute.
}
public void MyMethod<[MustBeVariant] T>(T variant)
{
// Do something with variant.
}