c_sharp_features.rst 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. .. _doc_c_sharp_features:
  2. Features
  3. ============
  4. This page provied an overview over the commonly used features of both C# and Godot
  5. and how they are used together.
  6. Type Conversion and Casting
  7. ---------------------------
  8. C# is a statically typed language. Therefore you can't do the following:
  9. .. code-block:: csharp
  10. var mySprite = GetNode("MySprite")
  11. mySprite.SetFrame(0)
  12. The method ``GetNode()`` returns a ``Node`` instance.
  13. You must explicitly convert it to the desired derived type, ``Sprite`` in this case.
  14. For this, you have various options in C#.
  15. **Casting and Type Checking**
  16. Throws ``InvalidCastException`` if the returned node cannot be casted to Sprite.
  17. You would use it instead of the ``as`` operator if you are pretty sure it won't fail.
  18. .. code-block:: csharp
  19. Sprite mySprite = (Sprite)GetNode("MySprite");
  20. mySprite.SetFrame(0);
  21. **Using the AS operator**
  22. The ``as`` operator returns null if the node cannot be casted to Sprite,
  23. and for this reason it cannot be used with value types.
  24. .. code-block:: csharp
  25. Sprite mySprite = GetNode("MySprite") as Sprite;
  26. // Only call SetFrame() is mySprite is not null
  27. mySprite?.SetFrame(0);;
  28. **Type checking using the IS operator**
  29. To check if the node can be casted to Sprite, you can use the ``is`` operator.
  30. The ``is`` operator returns false if the node cannot be casted to Sprite,
  31. otherwise it returns true.
  32. .. code-block:: csharp
  33. if (GetNode("MySprite") is Sprite)
  34. {
  35. // Yup, it's a sprite!
  36. }
  37. For more advanced type checking, you can look into `Pattern Matching <https://docs.microsoft.com/en-us/dotnet/csharp/pattern-matching>`_.
  38. Signals
  39. -------
  40. For a complete C# example, see the **Handling a signal** section in the step by step :ref:`doc_scripting` tutorial.
  41. Declaring a signal in C# is done with the ``[Signal]`` attribute on a delegate.
  42. .. code-block:: csharp
  43. [Signal]
  44. delegate void MySignal();
  45. [Signal]
  46. delegate void MySignalWithArguments(string foo, int bar);
  47. These signals can then be connected either in the editor or from code with ``Connect``.
  48. .. code-block:: csharp
  49. public void MyCallback()
  50. {
  51. GD.Print("My callback!");
  52. }
  53. public void MyCallbackWithArguments(string foo, int bar)
  54. {
  55. GD.Print("My callback with: ", foo, " and ", bar, "!");
  56. }
  57. public void SomeFunction()
  58. {
  59. instance.Connect("MySignal", this, "MyCallback");
  60. instance.Connect(nameof(MySignalWithArguments), this, "MyCallbackWithArguments");
  61. }
  62. Emitting signals is done with the ``EmitSignal`` method.
  63. .. code-block:: csharp
  64. public void SomeFunction()
  65. {
  66. EmitSignal(nameof(MySignal));
  67. EmitSignal("MySignalWithArguments", "hello there", 28);
  68. }
  69. Notice that you can always reference a signal name with the ``nameof`` keyword (applied on the delegate itself).
  70. Finally, signals can be created by calling ``AddUserSignal``, but be aware that it should be executed before any use of said signals (with ``Connect`` or ``EmitSignal``).
  71. .. code-block:: csharp
  72. public void SomeFunction()
  73. {
  74. AddUserSignal("MyOtherSignal");
  75. EmitSignal("MyOtherSignal");
  76. }