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。當 Variant 型別完全未知時這會很有用。不過,建議仍盡量使用更具體的轉換。Variant.Obj 會對 Variant.VariantType 做 switch 判斷,這可能並非必要。此外,如果結果是值型別,則會發生 boxing。
舉例來說,如果你不能接受 Variant.As<MyNode>() 可能丟出無效轉型例外,可以改用 Variant.As<GodotObject>() is MyNode n 這種型別模式。
備註
由於 C# 中的 Variant 型別是 struct,無法為 null。若要建立「null」的 Variant,請使用 default 關鍵字或 Godot.Variant 的無參數建構式。
Variant 相容型別
Variant 相容型別可以與 Godot.Variant 互相轉換。以下 C# 型別皆為 Variant 相容型別:
所有 內建值型別,除了
decimal、nint與nuint。string。繼承自 GodotObject 的類別。
在
Godot.Collections命名空間定義的集合型別。
Variant 型別與其對應 C# 型別的完整列表:
Variant 型別 |
C# 型別 |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
警告
Godot 在 Variant 中使用 64 位元整數與浮點數。較小的整數與浮點型別(例如 int、short、float)因可被容納於較大型別中而受到支援。請注意,執行轉型時若使用錯誤的型別,可能會導致精度損失。
警告
Godot.Variant 支援 enum,因為 enum 的基礎型別為相容的整數型別。不過,enum 並無隱式轉換,必須手動轉為其底層整數型別後,才能轉換為 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
使用泛型時,你可以透過 [MustBeVariant] 屬性,限制泛型 T 僅能為 Variant 相容型別之一。
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.
}