[Proposal] File Scoped Type Declaration #8335
-
File Scoped Type Declaration
SummarySimilar to file scoped namespace declarations, file scoped type declarations allow the definition of a single struct, class, or record per file without brackets. MotivationC# has a long history of use in scenarios where C# code is written in small snippets of file-scoped behavior (sometimes referred to as "scripting"). The primary example being scripting functionality in game engines like Unity, Godot, Stride, and others. In some cases, these engines support C# along with other language options. For example, Godot supports C# and GDScript natively, and other language options through community supported extensions. Often, the alternative to C# is a language designed with scripting in mind, and so has a more lightweight syntax compared to C#: Example C# script in Godot: // Player.cs
using Godot;
public partial class Player : Area2D
{
[Export]
public int Speed { get; set; } = 400; // How fast the player will move (pixels/sec).
public Vector2 ScreenSize; // Size of the game window.
public override void _Ready()
{
ScreenSize = GetViewportRect().Size;
}
} And an equivalent script in GDScript: # Player.gd
# (optional) class definition:
# class_name Player
# inheritance:
extends Area2D
@export var speed = 400 # How fast the player will move (pixels/sec).
var screen_size # Size of the game window.
func _ready():
screen_size = get_viewport_rect().size We can ignore other differences in syntax, like syntactically significant whitespace and lack of semicolons and focus on indentation (by convention if not syntactically enforced) and brackets. This proposal seeks to improve quality-of-life for this use case by introducing a syntax for a file-scoped type declaration. With a file-scoped type declaration, the above C# script could be written this way: // Player.cs
using Godot;
// Class name is removed. File name MUST be valid identifier, before the extension
public partial class : Area2D;
[Export]
public int Speed { get; set; } = 400; // How fast the player will move (pixels/sec).
public Vector2 ScreenSize; // Size of the game window.
public override void _Ready()
{
ScreenSize = GetViewportRect().Size;
} In terms of quality-of-life, this narrows the gap significantly relative to purpose-built scripting languages like GDScript be reducing unnecessary indentation and brackets. At the same time, this syntax should integrate well with other functionality, like primary constructors. Some additional examples: // Player.cs
// minimal example:
public class;
public int Speed { get; set; } = 400; // Player.cs
// primary constructor is supported
public class(int primaryCtorArg);
private int _field = primaryCtorArg; // Vector2d.cs
// structs are also supported
public struct;
public float X { get; set; }
public float Y { get; set; } // Player.cs
// records are also supported
public record(int PrimaryCtorArg);
public override ToString() => $"PrimaryCtorArg: {PrimaryCtorArg}"; Note that for records, the lack of a type name disambiguates a short-form record definition from a file-scoped one. // Player.cs
// can be used with classic namespace declaration:
namespace MyGame
{
public class;
} // Player.cs
// or more typically with file-scoped namespace declarations:
namespace MyGame;
public class; Note that the file-scoped type declaration must be specified first before any member definitions, and after an optional namespace declaration: // Player.cs
private int _field = 0;
private record ClassPrivateType(string Value);
public class; // ERROR: file-scoped type declarations must appear before any member definitions
namespace MyNamespace; // ERROR: namespace declarations must appear before file scoped type declarations The order requirement helps to disambiguate situations where a file-scoped type declaration, for example, includes class-scoped type declarations: // Player.cs
public class;
private PrivateClassScopedType _field = new();
private class PrivateClassScopedType {} Detailed DesignTBD DrawbacksTBD AlternativesTBD Unresolved QuestionsTBD Design MeetingsTBD |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment
-
Beta Was this translation helpful? Give feedback.
#928