Cache StringNames and NodePaths in implicit casts from string in C#
This pull request addresses https://github.com/godotengine/godot-proposals/discussions/10826 (please take a look). To summarise, StringNames and NodePaths are now cached when implicitly casting from strings to avoid allocations like:
Input.IsActionPressed("action"); // Created a StringName.
GetNode("path/to/node"); // Created a NodePath.
This pull request adds a FusionCache dependency since there is no cache built-in to C#. This could be replaced with a MemoryCache dependency, or an in-house solution could be created using a ConcurrentDictionary.
In my opinion, StringNames (and NodePaths) do not make sense in C# and should be removed from the API. The reason is the garbage collection spike issues I detailed in the discussion. There are very few benefits to StringNames since identifiers are generally less than 20 characters long, and NodePaths don't seem to provide any value.
That being said, as long as StringNames and NodePaths remain in the API, implicit allocations should not exist, especially when it's so common to use string literals as StringNames and NodePaths.
If this pull request is added, the developer can still opt for a non-cached StringName or NodePath using new StringName(string) or new NodePath(string).
Another related issue is there is currently no equality operator between StringName and string, so comparing them will result in the string being converted to a StringName, which is not ideal. It may be a good idea to add an == operator to StringName which accepts a string and compares them by converting the StringName to a string (instead of converting the string to a StringName).
By no means is this the only solution to the problem - I am open to discussions about better alternatives.