Godot vs. C# Collections with Linq methods / CS1929

Godot Version

4.6 Stable Mono Official

Question

I am having some issues using Generics and Linq queries with Godot collection types, but I feel what I’m trying to do should be quite straightforward, I think I’m just missing some small detail. I want to create an Array(Marker2D)’s from an Array(Node)’s, as shown here:

private Array<Node> treeSpawnSpaces;
...
{
        Random rand =  new Random();
        Tree tree = treeScene.Instantiate<Tree>();
        Array<Marker2D> markerArray = new Array<Marker2D>(treeSpawnSpaces.Where<Marker2D>((Node node) => node is Marker2D));
        
        int targetIndex = rand.Next() % markerArray.Count();
        tree.Position = markerArray[targetIndex].Position;
}

However, this implementation gives me error CS1929:

‘Array(Node)’ does not contain a definition for ‘Where’ and the best extension method overload ‘Queryable.Where(Marker2D)(IQueryable, Expression<Func<Marker2D, bool>>)’ requires a receiver of type ‘System.Linq.IQueryable<Godot.Marker2D>’

Changing the markerArray to an Array(Node) and using the generic Where() instead resolves this issue, but then I’m unable to access the Position of items in the array as the Node class doesn’t have Position. All I really need in this case is to be able to access this Position property from the items in the markerArray…

More generally, though, I have been having quite a few little typing errors when trying to use Linq operators on Godot collections. Is there something here I am missing in terms of best practices for querying Godot Collections? Should I simply be using C# Collections over Godot Collections instead? Any advice about best practices here would be greatly appreciated. Thanks!

Edit: Changed some angle brackets to round brackets as they seemed to just be deleted from my post

Edit 2: I have a partial answer to my question from a Reddit post, sharing it here for anyone in the future who might have the same question: Reddit

The gist of this is that since the Godot engine operates in C++, any time operations happen on Godot collections they have to be ‘marshalled’ into C++, meaning that if you don’t need specific interaction with the Engine or to access to the Variant type, it’s pretty much always better to use the C# collections and convert into Godot collections only when needed. Others, feel free to add to this or correct it if my understanding is wrong.

I’ve got a seemingly working (or at least not erroring) implementation of it now, based on C# Lists instead of Godot Arrays. Noteworthy: This solution also resolves the error if I use the Godot Array as well, so the change to a List isn’t required here as best I can tell.

List<Marker2D> markerArray = new List<Marker2D>(treeSpawnSpaces.Where((Node node) => node is Marker2D).Cast<Marker2D>());

It was resolved by using the generic Where() to filter to only Marker2D’s, then using Cast() to define the type of the IEnumerable afterwards. As far as I understand, if I did not pre-filter the list, this would cause an error anytime an item can’t be cast to the Marker2D type.