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.

C#-Variant

Für eine detaillierte Beschreibung von Variant im Allgemeinen, siehe die Variant-Dokumentationsseite.

Godot.Variant wird verwendet, um Godots nativen Typ Variant zu repräsentieren. Jeder Variant-kompatible Typ kann von/zu ihm konvertiert werden. Wir empfehlen, Godot.Variant zu vermeiden, es sei denn, es ist notwendig, mit nicht typisierten Engine-APIs zu interagieren. Nutzen Sie, wenn möglich, die Typsicherheit von C#.

Die Konvertierung von einem Variant-kompatiblen C#-Typ nach Godot.Variant kann durch implizite Konvertierungen erfolgen. Es gibt auch CreateFrom Methodenüberladungen und die generischen Variant.From<T> Methoden. Nur die Syntax ist anders: das Verhalten ist das gleiche.

int x = 42;
Variant numberVariant = x;
Variant helloVariant = "Hello, World!";

Variant numberVariant2 = Variant.CreateFrom(x);
Variant numberVariant3 = Variant.From(x);

Implizite Konvertierungen in Godot.Variant machen die Übergabe von Varianten als Methodenargumente sehr bequem. Zum Beispiel ist das dritte Argument von tween_property, das die endgültige Farbe des Tweens angibt, eine Godot.Variant.

Tween tween = CreateTween();
tween.TweenProperty(GetNode("Sprite"), "modulate", Colors.Red, 1.0f);

Die Konvertierung von Godot.Variant in einen C#-Typ kann durch explizite Konvertierungen erfolgen. Es gibt auch Variant.As{TYPE} Methoden und die generische Variant.As<T> Methode. Alle diese Methoden verhalten sich gleich.

int number = (int)numberVariant;
string hello = (string)helloVariant;

int number2 = numberVariant.As<int>();
int number3 = numberVariant.AsInt32();

Bemerkung

Die Variant.As{TYPE}-Methoden sind typischerweise nach C#-Typen benannt (Int32), nicht nach C#-Schlüsselwörtern (int).

Wenn der Typ der Variante nicht mit dem Typ des Konvertierungsziels übereinstimmt, hat dies je nach Quell- und Zielwert unterschiedliche Folgen.

  • Die Konvertierung kann den Wert untersuchen und einen ähnlichen, aber möglicherweise unerwarteten Wert des Zieltyps zurückgeben. Zum Beispiel kann der String "42a" in die Integer-Zahl 42 konvertiert werden.

  • Der Defaultwert des Zieltyps kann zurückgegeben werden.

  • Ein leeres Array kann zurückgegeben werden.

  • Eine Exception kann ausgelöst werden.

Die Konvertierung in den richtigen Typ vermeidet kompliziertes Verhalten und sollte bevorzugt werden.

Die Property Variant.Obj gibt ein C# Objekt mit dem korrekten Wert für jede Variante zurück. Dies kann nützlich sein, wenn der Typ der Variante völlig unbekannt ist. Wenn möglich, sollten Sie jedoch spezifischere Konvertierungen bevorzugen. Variant.Obj führt einen Switch auf Variant.VariantType aus und das ist vielleicht nicht notwendig. Wenn das Ergebnis ein Wertetyp ist, wird es außerdem in einen Rahmen gesetzt.

Wenn zum Beispiel die Möglichkeit, dass Variant.As<MyNode>() eine ungültige Cast-Ausnahme auslöst, nicht akzeptabel ist, sollten Sie stattdessen ein Pattern vom Typ Variant.As<GodotObject>() is MyNode n verwenden.

Bemerkung

Da der Variant-Typ in C# ein Struct ist, kann er nicht null sein. Um eine "null"-Variante zu erzeugen, verwenden Sie das Schlüsselwort default oder den parameterlosen Konstruktor Godot.Variant.

Variantenkompatible Typen

Ein Variant-kompatibler Typ kann in und aus einer Godot.Variant konvertiert werden. Diese C#-Typen sind Variant-kompatibel:

  • Alle Built-in-Werttypen außer decimal, nint und nuint.

  • string.

  • Von GodotObject abgeleitete Klassen.

  • Collections-Typen, die im Godot.Collections-Namespace definiert sind.

Vollständige Liste der Variantentypen und ihres entsprechenden C#-Typs:

Variant.Type

C#-Typ

Nil

null (kein Typ)

Bool

bool

Int

long (Godot speichert 64-Bit-Integer in Variant)

Float

double (Godot speichert 64-Bit-Floats in Variant)

String

string

Vector2

Godot.Vector2

Vector2I

Godot.Vector2I

Rect2

Godot.Rect2

Rect2I

Godot.Rect2I

Vector3

Godot.Vector3

Vector3I

Godot.Vector3I

Transform2D

Godot.Transform2D

Vector4

Godot.Vector4

Vector4I

Godot.Vector4I

Plane

Godot.Plane

Quaternion

Godot.Quaternion

Aabb

Godot.Aabb

Basis

Godot.Basis

Transform3D

Godot.Transform3D

Projection

Godot.Projection

Color

Godot.Color

StringName

Godot.StringName

NodePath

Godot.NodePath

Rid

Godot.Rid

Object

Godot.GodotObject oder ein abgeleiteter Typ.

Callable

Godot.Callable

Signal

Godot.Signal

Dictionary

Godot.Collections.Dictionary

Array

Godot.Collections.Array

PackedByteArray

byte[]

PackedInt32Array

int[]

PackedInt64Array

long[]

PackedFloat32Array

float[]

PackedFloat64Array

double[]

PackedStringArray

string[]

PackedVector2Array

Godot.Vector2[]

PackedVector3Array

Godot.Vector3[]

PackedVector4Array

Godot.Vector4[]

PackedColorArray

Godot.Color[]

Warnung

Godot verwendet 64-Bit-Integer und -Floats in Variant. Kleinere Integer- und Float-Typen wie int, short und float werden unterstützt, da sie in den größeren Typ passen. Beachten Sie, dass wenn eine Konvertierung durchgeführt wird, dass die Verwendung des falschen Typs zu einem möglichen Präzisionsverlust führt.

Warnung

Enums werden von Godot.Variant unterstützt, da ihr zugrundeliegender Typ ein Integer-Typ ist, die alle kompatibel sind. Allerdings gibt es keine impliziten Konvertierungen. Enums müssen manuell in ihren zugrundeliegenden Integer-Typ konvertiert werden, bevor sie in/aus Godot.Variant konvertiert werden können oder die generischen Methoden Variant.As<T> und Variant.From<T> verwenden, um sie zu konvertieren.

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>();

Verwendung von Variant in einem generischen Kontext

Bei der Verwendung von Generics kann es von Interesse sein, den generischen T-Typ darauf zu beschränken, dass er nur einer der Variant-kompatiblen Typen ist. Dies kann mit dem Attribut [MustBeVariant] erreicht werden.

public void MethodThatOnlySupportsVariants<[MustBeVariant] T>(T onlyVariant)
{
    // Do something with the Variant-compatible value.
}

Kombiniert mit dem generischen Variant.From<T> erlaubt es Ihnen, eine Instanz von Godot.Variant aus einer Instanz eines generischen T-Typs zu erhalten. Dann kann es in jeder API verwendet werden, die nur die Godot.Variant-Struktur unterstützt.

public void Method1<[MustBeVariant] T>(T variantCompatible)
{
    Variant variant = Variant.From(variantCompatible);
    Method2(variant);
}

public void Method2(Variant variant)
{
    // Do something with variant.
}

Um eine Methode mit einem generischen Parameter aufzurufen, der mit dem Attribut [MustBeVariant] versehen ist, muss der Wert ein Variant-kompatibler Typ oder ein generischer T-Typ sein, der ebenfalls mit dem Attribut [MustBeVariant] versehen ist.

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.
}