[.NET] Use collection expressions

As of C# 12 we can now use collection expressions to reduce some boilerplate when initializing collections.
This commit is contained in:
Raul Santos
2024-12-21 03:38:42 +01:00
parent 6d5fd9acc8
commit cea78730d0
14 changed files with 69 additions and 65 deletions
+5 -5
View File
@@ -377,7 +377,7 @@ like this:
// We are going to paint with this color.
Color godotBlue = new Color("478cbf");
// We pass the array of Vector2 to draw the shape.
DrawPolygon(_head, new Color[]{ godotBlue });
DrawPolygon(_head, [godotBlue]);
}
When running it you should see something like this:
@@ -474,7 +474,7 @@ draw the line, like this:
Color white = Colors.White;
Color godotBlue = new Color("478cbf");
DrawPolygon(_head, new Color[]{ godotBlue });
DrawPolygon(_head, [godotBlue]);
// We draw the while line on top of the previous shape.
DrawPolyline(_mouth, white, _mouthWidth);
@@ -535,7 +535,7 @@ its radius, and the third is its color:
Color godotBlue = new Color("478cbf");
Color grey = new Color("414042");
DrawPolygon(_head, new Color[]{ godotBlue });
DrawPolygon(_head, [godotBlue]);
DrawPolyline(_mouth, white, _mouthWidth);
// Four circles for the 2 eyes: 2 white, 2 grey.
@@ -589,7 +589,7 @@ like this:
Color godotBlue = new Color("478cbf");
Color grey = new Color("414042");
DrawPolygon(_head, new Color[]{ godotBlue });
DrawPolygon(_head, [godotBlue]);
DrawPolyline(_mouth, white, _mouthWidth);
DrawCircle(new Vector2(42.479f, 65.4825f), 9.3905f, white);
DrawCircle(new Vector2(85.524f, 65.4825f), 9.3905f, white);
@@ -652,7 +652,7 @@ to do it, like this:
Color godotBlue = new Color("478cbf");
Color grey = new Color("414042");
DrawPolygon(_head, new Color[]{ godotBlue });
DrawPolygon(_head, [godotBlue]);
DrawPolyline(_mouth, white, _mouthWidth);
DrawCircle(new Vector2(42.479f, 65.4825f), 9.3905f, white);
DrawCircle(new Vector2(85.524f, 65.4825f), 9.3905f, white);
+11 -11
View File
@@ -94,7 +94,7 @@ Under ``_ready()``, create a new Array.
.. code-tab:: csharp C#
var surfaceArray = new Godot.Collections.Array();
Godot.Collections.Array surfaceArray = [];
This will be the array that we keep our surface information in - it will hold
all the arrays of data that the surface needs. Godot will expect it to be of
@@ -108,7 +108,7 @@ size ``Mesh.ARRAY_MAX``, so resize it accordingly.
.. code-tab:: csharp C#
var surfaceArray = new Godot.Collections.Array();
Godot.Collections.Array surfaceArray = [];
surfaceArray.Resize((int)Mesh.ArrayType.Max);
Next create the arrays for each data type you will use.
@@ -123,10 +123,10 @@ Next create the arrays for each data type you will use.
.. code-tab:: csharp C#
var verts = new List<Vector3>();
var uvs = new List<Vector2>();
var normals = new List<Vector3>();
var indices = new List<int>();
List<Vector3> verts = [];
List<Vector2> uvs = [];
List<Vector3> normals = [];
List<int> indices = [];
Once you have filled your data arrays with your geometry you can create a mesh
by adding each array to ``surface_array`` and then committing to the mesh.
@@ -196,14 +196,14 @@ Put together, the full code looks like:
{
public override void _Ready()
{
var surfaceArray = new Godot.Collections.Array();
Godot.Collections.Array surfaceArray = [];
surfaceArray.Resize((int)Mesh.ArrayType.Max);
// C# arrays cannot be resized or expanded, so use Lists to create geometry.
var verts = new List<Vector3>();
var uvs = new List<Vector2>();
var normals = new List<Vector3>();
var indices = new List<int>();
List<Vector3> verts = [];
List<Vector2> uvs = [];
List<Vector3> normals = [];
List<int> indices = [];
/***********************************
* Insert code here to generate mesh.
@@ -259,7 +259,7 @@ tree structures.
{
private TreeNode _parent = null;
private List<TreeNode> _children = new();
private List<TreeNode> _children = [];
public override void _Notification(int what)
{
@@ -112,9 +112,9 @@ access.
{
if (EnemyScn == null)
{
return new string[] { "Must initialize property 'EnemyScn'." };
return ["Must initialize property 'EnemyScn'."];
}
return Array.Empty<string>();
return [];
}
}
+5 -5
View File
@@ -212,7 +212,7 @@ to do it for us:
.. code-tab:: csharp
// Use Godot's Array type instead of a BCL type so we can use `PickRandom()` on it.
private Godot.Collections.Array<string> _fruits = new Godot.Collections.Array<string> { "apple", "orange", "pear", "banana" };
private Godot.Collections.Array<string> _fruits = ["apple", "orange", "pear", "banana"];
public override void _Ready()
{
@@ -273,7 +273,7 @@ prevent repetition:
.. code-tab:: csharp
private string[] _fruits = { "apple", "orange", "pear", "banana" };
private string[] _fruits = ["apple", "orange", "pear", "banana"];
private string _lastFruit = "";
public override void _Ready()
@@ -450,8 +450,8 @@ get a value from another array as follows:
// Prints a random element using the weighted index that is returned by `RandWeighted()`.
// Here, "apple" will be returned twice as rarely as "orange" and "pear".
// "banana" is twice as common as "orange" and "pear", and four times as common as "apple".
string[] fruits = { "apple", "orange", "pear", "banana" };
float[] probabilities = { 0.5, 1, 1, 2 };
string[] fruits = ["apple", "orange", "pear", "banana"];
float[] probabilities = [0.5f, 1, 1, 2];
var random = new RandomNumberGenerator();
GD.Print(fruits[random.RandWeighted(probabilities)]);
@@ -501,7 +501,7 @@ ends up empty. When that happens, you reinitialize it to its default value:
.. code-tab:: csharp
private Godot.Collections.Array<string> _fruits = new() { "apple", "orange", "pear", "banana" };
private Godot.Collections.Array<string> _fruits = ["apple", "orange", "pear", "banana"];
// A copy of the fruits array so we can restore the original value into `fruits`.
private Godot.Collections.Array<string> _fruitsFull;
@@ -434,13 +434,13 @@ The following script uses the NavigationServer to parse source geometry from the
// If we did not parse a TileMap with navigation mesh cells we may now only
// have obstruction outlines so add at least one traversable outline
// so the obstructions outlines have something to "cut" into.
_sourceGeometry.AddTraversableOutline(new Vector2[]
{
_sourceGeometry.AddTraversableOutline(
[
new Vector2(0.0f, 0.0f),
new Vector2(500.0f, 0.0f),
new Vector2(500.0f, 500.0f),
new Vector2(0.0f, 500.0f),
});
]);
// Bake the navigation mesh on a thread with the source geometry data.
NavigationServer2D.BakeFromSourceGeometryDataAsync(_navigationMesh, _sourceGeometry, _callbackBaking);
@@ -615,16 +615,16 @@ The following script uses the NavigationServer to update a navigation region wit
NavigationServer2D.RegionSetMap(_regionRid, GetWorld2D().NavigationMap);
// Add vertices for a convex polygon.
_navigationMesh.Vertices = new Vector2[]
{
_navigationMesh.Vertices =
[
new Vector2(0, 0),
new Vector2(100.0f, 0),
new Vector2(100.0f, 100.0f),
new Vector2(0, 100.0f),
};
];
// Add indices for the polygon.
_navigationMesh.AddPolygon(new int[] { 0, 1, 2, 3 });
_navigationMesh.AddPolygon([0, 1, 2, 3]);
NavigationServer2D.RegionSetNavigationPolygon(_regionRid, _navigationMesh);
}
@@ -680,16 +680,16 @@ The following script uses the NavigationServer to update a navigation region wit
NavigationServer3D.RegionSetMap(_regionRid, GetWorld3D().NavigationMap);
// Add vertices for a convex polygon.
_navigationMesh.Vertices = new Vector3[]
{
_navigationMesh.Vertices =
[
new Vector3(-1.0f, 0.0f, 1.0f),
new Vector3(1.0f, 0.0f, 1.0f),
new Vector3(1.0f, 0.0f, -1.0f),
new Vector3(-1.0f, 0.0f, -1.0f),
};
];
// Add indices for the polygon.
_navigationMesh.AddPolygon(new int[] { 0, 1, 2, 3 });
_navigationMesh.AddPolygon([0, 1, 2, 3]);
NavigationServer3D.RegionSetNavigationMesh(_regionRid, _navigationMesh);
}
@@ -81,13 +81,13 @@ Obstacles are not involved in the source geometry parsing so adding them just be
.. code-tab:: csharp 2D C#
Vector2[] obstacleOutline = new Vector2[]
{
Vector2[] obstacleOutline
[
new Vector2(-50, -50),
new Vector2(50, -50),
new Vector2(50, 50),
new Vector2(-50, 50),
};
];
var navigationMesh = new NavigationPolygon();
var sourceGeometry = new NavigationMeshSourceGeometryData2D();
@@ -123,13 +123,13 @@ Obstacles are not involved in the source geometry parsing so adding them just be
.. code-tab:: csharp 3D C#
Vector3[] obstacleOutline = new Vector3[]
{
Vector3[] obstacleOutline =
[
new Vector3(-5, 0, -5),
new Vector3(5, 0, -5),
new Vector3(5, 0, 5),
new Vector3(-5, 0, 5),
};
];
var navigationMesh = new NavigationMesh();
var sourceGeometry = new NavigationMeshSourceGeometryData3D();
@@ -234,13 +234,13 @@ For static use an array of ``vertices`` is required.
NavigationServer2D.ObstacleSetRadius(newObstacleRid, 5.0f);
// Use obstacle static by adding a square that pushes agents out.
Vector2[] outline = new Vector2[]
{
Vector2[] outline =
[
new Vector2(-100, -100),
new Vector2(100, -100),
new Vector2(100, 100),
new Vector2(-100, 100),
};
];
NavigationServer2D.ObstacleSetVertices(newObstacleRid, outline);
// Enable the obstacle.
@@ -280,13 +280,13 @@ For static use an array of ``vertices`` is required.
NavigationServer3D.ObstacleSetRadius(newObstacleRid, 5.0f);
// Use obstacle static by adding a square that pushes agents out.
Vector3[] outline = new Vector3[]
{
Vector3[] outline =
[
new Vector3(-5, 0, -5),
new Vector3(5, 0, -5),
new Vector3(5, 0, 5),
new Vector3(-5, 0, 5),
};
];
NavigationServer3D.ObstacleSetVertices(newObstacleRid, outline);
// Set the obstacle height on the y-axis.
NavigationServer3D.ObstacleSetHeight(newObstacleRid, 1.0f);
@@ -169,14 +169,14 @@ Afterwards the function waits for the next physics frame before continuing with
// Create a procedural navigation mesh for the region.
var newNavigationMesh = new NavigationMesh()
{
Vertices = new[]
{
Vertices =
[
new Vector3(0.0f, 0.0f, 0.0f),
new Vector3(9.0f, 0.0f, 0.0f),
new Vector3(0.0f, 0.0f, 9.0f),
},
],
};
int[] polygon = new[] { 0, 1, 2 };
int[] polygon = [0, 1, 2];
newNavigationMesh.AddPolygon(polygon);
NavigationServer3D.RegionSetNavigationMesh(region, newNavigationMesh);
+5 -1
View File
@@ -139,7 +139,11 @@ It will connect and fetch a website.
Debug.Assert(http.GetStatus() == HTTPClient.Status.Connected); // Check if the connection was made successfully.
// Some headers.
string[] headers = { "User-Agent: Pirulo/1.0 (Godot)", "Accept: */*" };
string[] headers =
[
"User-Agent: Pirulo/1.0 (Godot)",
"Accept: */*",
];
err = http.Request(HTTPClient.Method.Get, "/ChangeLog-5.php", headers); // Request a page from the site.
Debug.Assert(err == Error.Ok); // Make sure all is OK.
+2 -2
View File
@@ -127,7 +127,7 @@ But what if you need to send data to the server? Here is a common way of doing i
.. code-tab:: csharp
string json = Json.Stringify(dataToSend);
string[] headers = new string[] { "Content-Type: application/json" };
string[] headers = ["Content-Type: application/json"];
HttpRequest httpRequest = GetNode<HttpRequest>("HTTPRequest");
httpRequest.Request(url, headers, HttpClient.Method.Post, json);
@@ -147,7 +147,7 @@ For example, to set a custom user agent (the HTTP ``User-Agent`` header) you cou
.. code-tab:: csharp
HttpRequest httpRequest = GetNode<HttpRequest>("HTTPRequest");
httpRequest.Request("https://api.github.com/repos/godotengine/godot/releases/latest", new string[] { "User-Agent: YourCustomUserAgent" });
httpRequest.Request("https://api.github.com/repos/godotengine/godot/releases/latest", ["User-Agent: YourCustomUserAgent"]);
.. danger::
+2 -2
View File
@@ -224,7 +224,7 @@ from a CharacterBody2D or any other collision object node:
{
var spaceState = GetWorld2D().DirectSpaceState;
var query = PhysicsRayQueryParameters2D.Create(globalPosition, playerPosition);
query.Exclude = new Godot.Collections.Array<Rid> { GetRid() };
query.Exclude = [GetRid()];
var result = spaceState.IntersectRay(query);
}
}
@@ -263,7 +263,7 @@ member variable. The array of exceptions can be supplied as the last argument as
{
var spaceState = GetWorld2D().DirectSpaceState;
var query = PhysicsRayQueryParameters2D.Create(globalPosition, targetPosition,
CollisionMask, new Godot.Collections.Array<Rid> { GetRid() });
CollisionMask, [GetRid()]);
var result = spaceState.IntersectRay(query);
}
}
@@ -518,12 +518,12 @@ The default value of Godot arrays is null. A different default can be specified:
.. code-block:: csharp
[Export]
public Godot.Collections.Array<string> CharacterNames { get; set; } = new Godot.Collections.Array<string>
{
public Godot.Collections.Array<string> CharacterNames { get; set; } =
[
"Rebecca",
"Mary",
"Leah",
};
];
Arrays with specified types which inherit from resource can be set by
drag-and-dropping multiple files from the FileSystem dock.
@@ -588,11 +588,11 @@ The default value of C# arrays is null. A different default can be specified:
.. code-block:: csharp
[Export]
public Vector3[] Vectors { get; set; } = new Vector3[]
{
public Vector3[] Vectors { get; set; } =
[
new Vector3(1, 2, 3),
new Vector3(3, 2, 1),
}
];
Setting exported variables from a tool script
---------------------------------------------
@@ -212,7 +212,7 @@ to said method.
// Outputs "Hello there!" twice, once per line.
myGDScriptNode.Call("print_n_times", "Hello there!", 2);
string[] arr = new string[] { "a", "b", "c" };
string[] arr = ["a", "b", "c"];
// Output: "a", "b", "c" (one per line).
myGDScriptNode.Call("print_array", arr);
// Output: "1", "2", "3" (one per line).
+2 -2
View File
@@ -220,7 +220,7 @@ So let's initialize an array of floats and create a storage buffer:
.. code-tab:: csharp
// Prepare our data. We use floats in the shader, so we need 32 bit.
var input = new float[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
float[] input = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
var inputBytes = new byte[input.Length * sizeof(float)];
Buffer.BlockCopy(input, 0, inputBytes, 0, inputBytes.Length);
@@ -251,7 +251,7 @@ assign it to a uniform set which we can pass to our shader later.
Binding = 0
};
uniform.AddId(buffer);
var uniformSet = rd.UniformSetCreate(new Array<RDUniform> { uniform }, shader, 0);
var uniformSet = rd.UniformSetCreate([uniform], shader, 0);
Defining a compute pipeline