(C#) How to get snake_case from reflected property?

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

I want to write an extension method that safely calls the Tween function, based on a property.
For example, Node2D has a SelfModulate property. However, Tween should be called with self_modulate.

How can I go from the C# property (which I have as a reflected PropertyInfo) to the correct Godot snake_case name?

Ideally, my code would look like:

Type type = Type.GetType("Godot.Node2D, GodotSharp");
PropertyInfo propInfo = type.GetProperty("SelfModulate");

???

GD.Print(snakeCaseName); // outputs "self_modulate"

I want to do this safely, not just via some sort of automatic Camel to Snake string converter
I feel like GD.ClassDB.ClassGetPropertyList() gets me almost all the way there, but not quite. I get a list of proper snake_case properties, but no matching C# equivalents.

Cheers!

:bust_in_silhouette: Reply From: gnumaru

Unfortunately there’s probably no way of doing this in an exact safe way.

In order to find the match between a C# property name and a native property name, you could remove the underscores, convert both to lower/upper case and search the identical matches. Or instead of searching identical strings, you could use the similarity index (the String.similarity method).

I think it would be nice to create a proposal to annotate the C# properties and methods with the name of every class members (method, property, signal etc), this way one could easily get the exact native names for the class members.

There are native case convertor functions, which I could try (match both ways, see if there is overlap), which will be relatively safe, but not ideal.

ThomasKole | 2023-02-24 11:50

Yep, there are the String.to_camel_case, String.to_pascal_case and String.to_snake_case methods. But there’s no guarantee that the conversion done to the C# class member names is exactly the same performed by those methods.

Probably removing underscores, converting both to lower/upper case and searching exact matches is a bit more reliable than converting the C# name to snake case (or the native name to pascal case) and searching exact matches.

But the best way would be having this info embedded in the C# classes as member attributes. There shouldn’t be a core (c++) function for this, because the .net runtime is just an extension, there could be any number of runtime extensions (lua, javascript, python, ruby etc) that could use different names, so it would be better if each script runtime implementation had its own way of telling the correspondence between the native class member names and the script runtime names. In most languages that support annotations (called attributes in .net) using annotations is probably one of the most straightforward way of doing this.

But, let’s be honest that the most simple approach is just tweening String.ToSnakeCase(nameof(object.SelfModulate)). If it never fails, you never have to care about it. But IF one day it fails, THEN you do something about it =).

gnumaru | 2023-02-24 12:10