- 
          
- 
                Notifications
    You must be signed in to change notification settings 
- Fork 23.5k
[.Net] Implment Opt-in Automatic Null Check for Exported Members #112195
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
| 
 Thanks for the help from the members of the dotnet/runtime that pointed out the existence of the  | 
| Since  
 | 
| 
 That's a good point. I guess we need a better access point in the object initialization workflow to insert these checks. | 
| The nullability warning now has proper suppressions. | 
| 
 🤔 I guess any web request in CI can fail these days | 
| Now packed array types and string / StringNames are also included, e.g. Are initialized to Array.Empty and string.Empty if unchanged in inspector. TLDR:     [Export] private Node _targetNode;
    [Export] private Resource _targetResource;
    [Export] private string _targetString;
    [Export] private StringName _targetStringName;
    [Export] private int[] _targetIntArray;
    [Export] private Godot.Collections.Array<int> _targetGodotIntArray;
    [Export] private Godot.Collections.Dictionary<string, int> _targetGodotDictionary;Will have the following checks: protected override void ValidateExportedProperties()
{
    if (this._targetNode == null) throw new global::System.NullReferenceException("The exported property/field '_targetNode' of type 'Godot.Node' is null.");
    if (this._targetResource == null) throw new global::System.NullReferenceException("The exported property/field '_targetResource' of type 'Godot.Resource' is null.");
    if (this._targetString == null) this._targetString = string.Empty;
    if (this._targetStringName == null) this._targetStringName = new global::Godot.StringName();
    if (this._targetIntArray == null) this._targetIntArray = global::System.Array.Empty<int>();
    if (this._targetGodotIntArray == null) throw new global::System.NullReferenceException("The exported property/field '_targetGodotIntArray' of type 'Godot.Collections.Array<int>' is null.");
    base.ValidateExportedProperties();
} | 
| 
 If types other than array and string throw if not assigned, surely array and string should also throw? They are both reference types. | 
| 
 I'm trying to match the GDScript's behavior here, as it is tricky to deterime the nullability for string and packed arrays when operating them in the inspector, see this example: extends Node
@export var _targetNode : Node;
@export var _targetResource : Resource;
@export var _targetString : String;
@export var _targetStringName : StringName;
@export var _targetIntArray : Array[int];
@export var _targetPackedIntArray : PackedInt32Array;
@export var _targetGodotDictionary : Dictionary[String, int];
func _ready() -> void:
	print(_targetNode);
	print(_targetResource);
	print(_targetString);
	print(_targetStringName);
	print(_targetIntArray);
	print(_targetPackedIntArray);
	print(_targetGodotDictionary);
Prints the following is nothing is assigned in inspector: As you see, unassigned  | 
| The reason I left  QQ2025111-01728.mp4 | 
This PR aims to enhance the usability of the Nullable Reference Type feature by introducing automatic checks for exported members via a new generated override on the virtual method
ValidateExportedProperties.This feature is enabled under the following conditions:
<GodotEnableExportNullChecks>true</GodotEnableExportNullChecks>must be included in thecsprojfile.<Nullable>enable</Nullable>in thecsprojor by using#nullable enablein your code.?).With this improvement, users will no longer need to frequently write
* = null!for every not-null exported variable or perform null checks at every instance call. The binding will automatically check these values once the scene is created.To be specific, the following node type:
Would result in the following check code:
And the following resource type:
Would result in the following check code: