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...
Variante C#
Per una spiegazione dettagliata di Variant in generale, consultare la pagina di documentazione Variant.
Godot.Variant è utilizzato per rappresentare il tipo nativo di Godot Variant. Qualsiasi tipo compatibile con Variant si può convertire da/a esso. Si consiglia di evitare Godot.Variant a meno che non sia necessario interagire con API non tipizzata del motore. È meglio sfruttare la sicurezza di tipo in C# quando possibile.
È possibile convertire da un tipo C# compatibile con Variant a Godot.Variant implicitamente. Esistono anche overload del metodo CreateFrom e i metodi generici Variant.From<T>. Solo la sintassi è diversa: il comportamento è lo stesso.
int x = 42;
Variant numberVariant = x;
Variant helloVariant = "Hello, World!";
Variant numberVariant2 = Variant.CreateFrom(x);
Variant numberVariant3 = Variant.From(x);
Le conversioni implicite in Godot.Variant rendono molto comodo il passaggio di varianti come argomenti per i metodi. Ad esempio, il terzo argomento di tween_property che specifica il colore finale del tween è un Godot.Variant.
Tween tween = CreateTween();
tween.TweenProperty(GetNode("Sprite"), "modulate", Colors.Red, 1.0f);
È possibile convertire da Godot.Variant a un tipo di C# esplicitamente. Esistono anche i metodi Variant.As{TYPE} e il metodo generico Variant.As<T>. Tutti si comportano allo stesso modo.
int number = (int)numberVariant;
string hello = (string)helloVariant;
int number2 = numberVariant.As<int>();
int number3 = numberVariant.AsInt32();
Nota
I metodi Variant.As{TYPE} in genere derivano il nome dai tipi di C# (Int32), non dalle parole chiave di C# (int).
Se il tipo Variant non corrisponde al tipo di destinazione della conversione, le conseguenze variano a seconda dei valori di origine e di destinazione.
La conversione potrebbe esaminare il valore e restituire un valore simile ma potenzialmente inaspettato del tipo di destinazione. Ad esempio, la stringa
"42a"potrebbe essere convertita nell'intero42.Potrebbe essere restituito il valore predefinito del tipo di destinazione.
Potrebbe essere restituito un array vuoto.
Potrebbe essere generata un'eccezione.
La conversione al tipo corretto evita comportamenti complicati e si dovrebbe preferire.
La proprietà Variant.Obj restituisce un object C# con il valore corretto per qualsiasi variante. Ciò potrebbe essere utile quando il tipo di Variant è completamente sconosciuto. Tuttavia, quando possibile, è preferibile effettuare conversioni più specifiche. Variant.Obj valuta uno switch su Variant.VariantType e potrebbe non essere necessario. Inoltre, se il risultato è un tipo di valore, viene "imballato".
Ad esempio, se non è accettabile che Variant.As<MyNode>() possa generare un'eccezione di conversione non valida, si può considerare l'utilizzo di un type pattern Variant.As<GodotObject>() is MyNode n.
Nota
Poiché il tipo Variant in C# è una struct, non può essere null. Per creare un Variant "null", utilizzare la parola chiave default o il costruttore senza parametri di Godot.Variant.
Tipi compatibili con Variant
Un tipo compatibile con Variant può essere convertito in e da Godot.Variant. I seguenti tipi C# sono compatibili con Variant:
Tutti i tipi integrati di valore, tranne
decimal,nintenuint.string.Classi derivate da GodotObject.
I tipi di raccolte definiti nello spazio dei nomi
Godot.Collections.
Elenco completo dei tipi Variant e del loro tipo equivalente di C#:
Variant.Type |
Tipo di C# |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Avvertimento
Godot utilizza interi e float a 64 bit in Variant. Sono supportati tipi interi e float più piccoli come int, short e float, poiché si possono inserire nel tipo più grande. Si tenga presente che, quando si effettua una conversione, utilizzare un tipo errato risulterà in una potenziale perdita di precisione.
Avvertimento
Le enumerazioni sono supportate da Godot.Variant poiché il loro tipo sottostante è un tipo intero, con cui sono tutti compatibili. Tuttavia, non esistono conversioni implicite: è necessario convertire manualmente le enumerazioni nel loro tipo intero sottostante prima di poterle da/a Godot.Variant, oppure utilizzare i metodi generici Variant.As<T> e Variant.From<T> per convertirle.
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>();
Utilizzare Variant in un contesto generico
Quando si utilizzano i generici, potrebbe essere interessante limitare il tipo generico T a uno solo dei tipi compatibili con Variant. Questo si può ottenere attraverso l'attributo [MustBeVariant].
public void MethodThatOnlySupportsVariants<[MustBeVariant] T>(T onlyVariant)
{
// Do something with the Variant-compatible value.
}
In combinazione con il tipo generico Variant.From<T>, è possibile ottenere un'istanza di Godot.Variant da un'istanza di un tipo generico T. Si può quindi utilizzare in qualsiasi API che supporta solo la struct Godot.Variant.
public void Method1<[MustBeVariant] T>(T variantCompatible)
{
Variant variant = Variant.From(variantCompatible);
Method2(variant);
}
public void Method2(Variant variant)
{
// Do something with variant.
}
Per richiamare un metodo con un parametro generico annotato con l'attributo [MustBeVariant], il valore deve essere un tipo compatibile con Variant o un tipo generico T anch'esso annotato con l'attributo [MustBeVariant].
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.
}