How would I test if a Node is a Control node or any of its subclasses using C#?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Y_VRN

I’m currently practicing C# in Godot, and I’ve gotten stuck with testing for Node classes. If I recall, GDScript uses the is keyword, such as var IsControl = somePanel is Control. However, in C#, I cannot escape the errors with type checking. What I currently have is this:

internal ARL _get_content_descendants(Control item, ARL _master_array) {
	ARL Descendants = (_master_array is ARL)? _master_array : new ARL();
	
	foreach (var Child in item.GetChildren()) {
		if (Child is Control) {
			var _child = (Control) Child;
			Descendants.Add(_child);
			
			if (_child.GetChildCount() > 0) {
				_get_content_descendants(_child, Descendants);
			}
		}
	}
	
	return Descendants;
}
---------------------------------------------------------------
C:\Users\*****\Documents\GD Practice\Test User Interface\ScrollPanel.cs(102,50): Cannot convert type 'Godot.Panel' to 'Control'
C:\Users\*****\Documents\GD Practice\Test User Interface\ScrollPanel.cs(103,19): 'object' does not contain a definition for 'Name' and no accessible extension method 'Name' accepting a first argument of type 'object' could be found (are you missing a using directive or an assembly reference?)

I don’t know what (else) I am missing or doing wrong.

Strange. Try being more specific with your casting?

if (Child is Godot.Control) {
            var _child = (Godot.Control) Child;

The as operator should fail silently if you just want to move on.

Control ControlChild = Child as Control;
if (ControlChild != null) 

timothybrentwood | 2022-12-20 06:21

It appears that using Godot.Control was the solution. I was slightly confused as to what could the Control type alone meant, or it probably doesnt exist? Thanks for the help!

Y_VRN | 2022-12-21 01:04

I copied your code directly into a fresh project and it worked for me. I just printed the node if it was a control and attached a node2d and panel to the parent node.

If you’re having to specify Godot.Control vs just Control it says to me that your namespace is cluttered and the compiler couldn’t resolve which Control to use. (OR your solution/project build settings are different than mine/default?) I don’t think you’d get a compile time error because it doesn’t know au priori the object types returned by item.GetChildren().

Add using Godot; to the top of your script if it isn’t already there then try just using Control instead of Godot.Control again. (If you don’t have using Godot; at the top that explains the error.)

timothybrentwood | 2022-12-21 06:32

:bust_in_silhouette: Reply From: GlitchedCode

I have not touched the c# in godot in quite sometime so I could be wrong here but, can you not call IsClass(“Control”) on the node you want to check? If so this would either return as true or false.

example

if (Child.IsClass("Control"))
{
    // node is a Control node or one of its subclasses, do what you want with said node.
    Descendants.Add(Child);
}