godot: C# abstract Godot types missing constructors

Godot version

3.4.stable

System information

macOS Big Sur, 2017 iMac, i7

Issue description

When trying to extend a CanvasItem in C#, Godot throws an error saying that /Users/.../ShowInGame.cs(4,14): 'CanvasItem' does not contain a constructor that takes 0 arguments. However, the C# metadata for CanvasItem does not contain a constructor and I can find no documentation for it on the internet. Is CanvasItem not intended to be extended? If so, why expose it as an extendable class?

Here is my code trying to extend CanvasItem:

using Godot;
using System;

public class ShowInGame : CanvasItem
{
    public override void _Ready()
    {
        Visible = true;

        base._Ready();
    }
}

Steps to reproduce

If you try to compile, run, or build the project, you can see the error described above.

Minimal reproduction project

MinCanvasItemError.zip

About this issue

  • Original URL
  • State: open
  • Created 3 years ago
  • Reactions: 7
  • Comments: 19 (12 by maintainers)

Most upvoted comments

Personally I think extending should be allowed, I think it works in GDScript so it should work in C# too.

Unfortunately, I think the abstract keyword will be removed in the future (4.1?) because with the switch from Mono to CLR these classes can no longer be abstract (they are instantiated by the editor, Mono allowed us to instantiate abstract classes but I believe that’s not possible with the CLR).

Therefore, without the abstract keyword the only way to prevent users from instantiating these classes is to hide the constructor (that’s why it’s internal, it can be instantiated by the editor but not the user).

See the core issue I linked above: https://github.com/godotengine/godot/issues/55549#issuecomment-1061855184

@reduz is reworking this as it’s a problem for GDExtension too. We’re going to lift the limitation that virtual classes can’t be instantiated for some of them (not all, as some still don’t make sense to instantiate, like CanvasItem - but BaseButton or Texture do when properly extended).

I have run into this issue again with Texture and StyleBox. The StyleBox one was especially annoying, as Themes require it to be derived from StyleBox. Had to abandon themes to get what I wanted.

You can still use any type derived from StyleBox or Texture. E.g. StyleBoxFlat.

This issue should only be a problem for users who want to implement their own custom Texture or StyleBox type without basing it on an existing instantiable type. We’re working on fixing this in 4.0.

CanvasItem is a non-instantiable class, therefore the bindings_generator.cpp generates an internal constructor when generating the C# class. Since the constructor is internal your class can’t call it.

The reason why it’s exposed as a public class is that some public methods may use it as the type of their parameters or the return type, so you need access to it.


Duplicate of #35482