From 4c39a88a42f2494ee799862f6afdce0e94f8b846 Mon Sep 17 00:00:00 2001 From: 31 <31eee384@gmail.com> Date: Fri, 2 Feb 2024 00:29:18 -0800 Subject: [PATCH 1/4] c_sharp_variant.rst: add more examples, fix explicit vs. implicit --- .../scripting/c_sharp/c_sharp_variant.rst | 64 +++++++++++++++++-- 1 file changed, 57 insertions(+), 7 deletions(-) diff --git a/tutorials/scripting/c_sharp/c_sharp_variant.rst b/tutorials/scripting/c_sharp/c_sharp_variant.rst index c68035a2472..a4b534fd5fa 100644 --- a/tutorials/scripting/c_sharp/c_sharp_variant.rst +++ b/tutorials/scripting/c_sharp/c_sharp_variant.rst @@ -9,17 +9,67 @@ For a detailed explanation of Variant in general, see the :ref:`Variant `` method can be used to convert -a ``Godot.Variant`` to a C# type. Since the ``Godot.Variant`` type contains implicit conversions -defined for all the supported types, calling these methods directly is usually not necessary. +Converting from a supported type to ``Godot.Variant`` can be done using implicit conversions. Also +available are ``CreateFrom`` method overloads and the generic ``Variant.From`` methods. -Use ``CreateFrom`` method overloads or the generic ``Variant.From`` method to convert a C# type -to a ``Godot.Variant``. +.. code-block:: csharp + + int x = 42; + Godot.Variant number = x; + Godot.Variant hello = "Hello, World!"; + + Godot.Variant number2 = Godot.Variant.CreateFrom(x); + Godot.Variant number3 = Godot.Variant.From(x); + +Implicit conversions to ``Godot.Variant`` make passing variants as method arguments very convenient. +For example, ``final_val`` of :ref:`tween_property`. + +.. code-block:: csharp + + Tween tween = CreateTween(); + tween.TweenProperty(GetNode("Sprite"), "modulate", Colors.Red, 1.0f); + +Converting from ``Godot.Variant`` to a supported type can be done using explicit conversions. Also +available are ``Variant.As{TYPE}`` methods or the generic ``Variant.As`` method. + +.. code-block:: csharp + + int cSharpNumber = (int)number; + string cSharpHello = (string)hello; + + int cSharpNumber2 = number.As(); + string cSharpHello2 = hello.AsString(); + +.. note:: + + All methods of converting from ``Godot.Variant`` to a C# type behave the same way. If conversion + is not possible, the default value of the target type or an empty array is returned. An + exception is not thrown. + +A matching type is not necessary for a conversion to succeed. For example, all variants are +convertible to ``string``. + +.. code-block:: csharp + + string s = Variant.From(new Vector3(1, 3, 9)).As(); + GD.Print(s); // (1, 3, 9) + +Some C# types are not directly represented by ``Variant.Type``. The ``Variant.As{TYPE}`` method uses +a more specific name to represent them. + +.. code-block:: csharp + + int cSharpNumber3 = number.AsInt32(); + +To convert ``Godot.Variant`` to a C# ``object`` without specifying a more specific target type, use +the ``Variant.Obj`` property. This can be used to compare two variants that both have unknown types +using the equality operator ``==``. When possible, prefer more specific conversions. ``Variant.Obj`` +may result in unnecessary boxing of value types. .. note:: Since the Variant type in C# is a struct, it can't be null. To create a "null" - Variant use the ``default`` keyword or the parameterless constructor. + Variant, use the ``default`` keyword or ``Godot.Variant`` parameterless constructor. Variant-compatible types ------------------------ @@ -79,7 +129,7 @@ Variant.Type C# Type Godot uses 64-bit integers and floats in Variant. Smaller integer and float types such as ``int``, ``short`` and ``float`` are supported since they can fit in the - bigger type. Be aware that an implicit conversion is performed so using the wrong + bigger type. Be aware that when a conversion is performed, using the wrong type will result in potential precision loss. .. warning:: From 2f94e1fd5c85621835d5f82226f0240b7fb7b2cc Mon Sep 17 00:00:00 2001 From: 31 <31eee384@gmail.com> Date: Sat, 3 Feb 2024 01:13:47 -0800 Subject: [PATCH 2/4] Changes and fixes from review --- .../scripting/c_sharp/c_sharp_variant.rst | 63 ++++++++++--------- 1 file changed, 32 insertions(+), 31 deletions(-) diff --git a/tutorials/scripting/c_sharp/c_sharp_variant.rst b/tutorials/scripting/c_sharp/c_sharp_variant.rst index a4b534fd5fa..f688136e548 100644 --- a/tutorials/scripting/c_sharp/c_sharp_variant.rst +++ b/tutorials/scripting/c_sharp/c_sharp_variant.rst @@ -9,62 +9,63 @@ For a detailed explanation of Variant in general, see the :ref:`Variant `` methods. +Converting from a Variant-compatible C# type to ``Godot.Variant`` can be done using implicit +conversions. Also available are ``CreateFrom`` method overloads and the generic ``Variant.From`` +methods. Only the syntax is different: the behavior is the same. .. code-block:: csharp int x = 42; - Godot.Variant number = x; - Godot.Variant hello = "Hello, World!"; + Variant numberVariant = x; + Variant helloVariant = "Hello, World!"; - Godot.Variant number2 = Godot.Variant.CreateFrom(x); - Godot.Variant number3 = Godot.Variant.From(x); + Variant numberVariant2 = Variant.CreateFrom(x); + Variant numberVariant3 = Variant.From(x); Implicit conversions to ``Godot.Variant`` make passing variants as method arguments very convenient. -For example, ``final_val`` of :ref:`tween_property`. +For example, the third argument of :ref:`tween_property` +specifying the final color of the tween is a ``Godot.Variant``. .. code-block:: csharp Tween tween = CreateTween(); tween.TweenProperty(GetNode("Sprite"), "modulate", Colors.Red, 1.0f); -Converting from ``Godot.Variant`` to a supported type can be done using explicit conversions. Also -available are ``Variant.As{TYPE}`` methods or the generic ``Variant.As`` method. +Converting from ``Godot.Variant`` to a C# type can be done using explicit conversions. Also +available are ``Variant.As{TYPE}`` methods or the generic ``Variant.As`` method. All of these +behave the same. .. code-block:: csharp - int cSharpNumber = (int)number; - string cSharpHello = (string)hello; + int number = (int)numberVariant; + string hello = (string)helloVariant; - int cSharpNumber2 = number.As(); - string cSharpHello2 = hello.AsString(); + int number2 = numberVariant.As(); + int number3 = numberVariant.AsInt32(); .. note:: - All methods of converting from ``Godot.Variant`` to a C# type behave the same way. If conversion - is not possible, the default value of the target type or an empty array is returned. An - exception is not thrown. + The ``Variant.As{TYPE}`` methods are typically named after C# types (``Int32``), not C# keywords + (``int``). -A matching type is not necessary for a conversion to succeed. For example, all variants are -convertible to ``string``. +If the Variant type doesn't match the conversion target type, the consequences vary depending on the +source and target values. -.. code-block:: csharp - - string s = Variant.From(new Vector3(1, 3, 9)).As(); - GD.Print(s); // (1, 3, 9) +- The conversion may examine the value and return a similar but potentially unexpected value of the + target type. For example, the string ``"42a"`` may be converted to the integer ``42``. +- The default value of the target type may be returned. +- An empty array may be returned. +- An exception may be thrown. -Some C# types are not directly represented by ``Variant.Type``. The ``Variant.As{TYPE}`` method uses -a more specific name to represent them. - -.. code-block:: csharp +Converting to the correct type avoids complicated behavior and should be preferred. - int cSharpNumber3 = number.AsInt32(); +The ``Variant.Obj`` property returns a C# ``object`` with the correct value for any variant. This +may be useful when the type of Variant is completely unknown. However, when possible, prefer more +specific conversions. ``Variant.Obj`` evaluates a ``switch`` on ``Variant.VariantType`` and it may +not be necessary. Also, if the result is a value type, it may be boxed when it normally wouldn't be. -To convert ``Godot.Variant`` to a C# ``object`` without specifying a more specific target type, use -the ``Variant.Obj`` property. This can be used to compare two variants that both have unknown types -using the equality operator ``==``. When possible, prefer more specific conversions. ``Variant.Obj`` -may result in unnecessary boxing of value types. +For example, if the potential for ``Variant.As()`` to throw a invalid cast exception isn't +acceptable, consider using a ``Variant.As() is MyNode n`` type pattern instead. .. note:: From c2e68a8dbe82bf953b07b67a0a75be13bf4bf0de Mon Sep 17 00:00:00 2001 From: 31 <331300+31@users.noreply.github.com> Date: Sat, 3 Feb 2024 03:41:27 -0600 Subject: [PATCH 3/4] Apply suggestions from code review Co-authored-by: A Thousand Ships <96648715+AThousandShips@users.noreply.github.com> --- tutorials/scripting/c_sharp/c_sharp_variant.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tutorials/scripting/c_sharp/c_sharp_variant.rst b/tutorials/scripting/c_sharp/c_sharp_variant.rst index f688136e548..899dd390ae7 100644 --- a/tutorials/scripting/c_sharp/c_sharp_variant.rst +++ b/tutorials/scripting/c_sharp/c_sharp_variant.rst @@ -10,7 +10,7 @@ We recommend avoiding ``Godot.Variant`` unless it is necessary to interact with Take advantage of C#'s type safety when possible. Converting from a Variant-compatible C# type to ``Godot.Variant`` can be done using implicit -conversions. Also available are ``CreateFrom`` method overloads and the generic ``Variant.From`` +conversions. There are also ``CreateFrom`` method overloads and the generic ``Variant.From`` methods. Only the syntax is different: the behavior is the same. .. code-block:: csharp @@ -31,9 +31,9 @@ specifying the final color of the tween is a ``Godot.Variant``. Tween tween = CreateTween(); tween.TweenProperty(GetNode("Sprite"), "modulate", Colors.Red, 1.0f); -Converting from ``Godot.Variant`` to a C# type can be done using explicit conversions. Also -available are ``Variant.As{TYPE}`` methods or the generic ``Variant.As`` method. All of these -behave the same. +Converting from ``Godot.Variant`` to a C# type can be done using explicit conversions. There are +also ``Variant.As{TYPE}`` methods and the generic ``Variant.As`` method. All of these behave the +same. .. code-block:: csharp @@ -70,7 +70,7 @@ acceptable, consider using a ``Variant.As() is MyNode n`` type patt .. note:: Since the Variant type in C# is a struct, it can't be null. To create a "null" - Variant, use the ``default`` keyword or ``Godot.Variant`` parameterless constructor. + Variant, use the ``default`` keyword or the ``Godot.Variant`` parameterless constructor. Variant-compatible types ------------------------ From d41f09fce64387dc845fe43e69446bbb2f4378d9 Mon Sep 17 00:00:00 2001 From: 31 <31eee384@gmail.com> Date: Sat, 3 Feb 2024 18:59:34 -0800 Subject: [PATCH 4/4] More directly describe .Obj boxing --- tutorials/scripting/c_sharp/c_sharp_variant.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tutorials/scripting/c_sharp/c_sharp_variant.rst b/tutorials/scripting/c_sharp/c_sharp_variant.rst index 899dd390ae7..b3a2d7440a3 100644 --- a/tutorials/scripting/c_sharp/c_sharp_variant.rst +++ b/tutorials/scripting/c_sharp/c_sharp_variant.rst @@ -62,7 +62,7 @@ Converting to the correct type avoids complicated behavior and should be preferr The ``Variant.Obj`` property returns a C# ``object`` with the correct value for any variant. This may be useful when the type of Variant is completely unknown. However, when possible, prefer more specific conversions. ``Variant.Obj`` evaluates a ``switch`` on ``Variant.VariantType`` and it may -not be necessary. Also, if the result is a value type, it may be boxed when it normally wouldn't be. +not be necessary. Also, if the result is a value type, it is boxed. For example, if the potential for ``Variant.As()`` to throw a invalid cast exception isn't acceptable, consider using a ``Variant.As() is MyNode n`` type pattern instead.