Home > Software engineering >  Enum.ToString() - use snake_case instead of PascalCase
Enum.ToString() - use snake_case instead of PascalCase

Time:10-24

Is there a way to make the default Enum.ToString() to convert to snake_case instead of PascalCase? And that change to be global, so I don't have to do that all over again.

public enum SpellTypes
{
    HorizonFocus
}

public sealed class Settings
{
    public Settings(SpellTypes types)
    {
        TypeString = types.ToString(); // actual: HorizonFocus, expected: horizon_focus
    }

    public string TypeString { get; }
}

In addition

I tried the following with Macross.Json.Extensions but it didn't apply the changes to the TypeString.

[JsonConverter(typeof(JsonStringEnumMemberConverter))]
public enum SpellTypes
{
    [EnumMember(Value = "horizon_focus")]
    HorizonFocus
}

CodePudding user response:

you can use readonly type instead of enum

public class SpellTypes
    {
    public static readonly SpellTypes HorizonFocus = new SpellTypes( 1, "Horizon_Focus" );
    public static readonly SpellTypes HorizonFocus2 = new SpellTypes( 2, "Horizon_Focus2" );
    public static readonly SpellTypes HorizonFocus3 = new SpellTypes( 3, "Horizon_Focus3" );
    public readonly int num;
    public readonly string name;

    private SpellTypes( int num, String name )
    {
        this.num = num;
        this.name = name;
    }
}

public sealed class Settings
{
    public Settings( SpellTypes types )
    {
        TypeString = types.name.ToString(); 
    }

    public string TypeString { get; }
}

CodePudding user response:

You could create an extension method for all enums.

You can cache the snake case names in a dictionary in a generic helper class, for performance.

public static string To_snake_case<T>(this T value) where T : Enum
{
    return SnakeCaseHelper.Values.TryGetValue(value, out var name) ? name : null;
}

private static class SnakeCaseHelper<T> where T : Enum
{
    public static Dictionary<T, string> Values = new();

    static SnakeCaseHelper()
    {
        var names = Enum.GetNames(typeof(T));
        var values = (T[])Enum.GetValues(typeof(T));
        for (var i = 0; i < values.Length; i  )
            Values[values[i]] = GetSnakeCase(names[1]);
    }

    static string GetSnakeCase(string text)
    {
        if(text.Length < 2)
            return text;

        var sb = new StringBuilder();
        sb.Append(char.ToLowerInvariant(text[0]));
        for(int i = 1; i < text.Length;   i)
        {
            char c = text[i];
            if(char.IsUpper(c))
            {
                sb.Append('_');
                sb.Append(char.ToLowerInvariant(c));
            }
            else
            {
                sb.Append(c);
            }
        }
        return sb.ToString();
    }
}

dotnetfiddle

Snake case function is from this answer.

  • Related