Enums.NET
Enums.NET copied to clipboard
[Feature] Custom EnumFormat with AllowMultiple
Always looking for the impossible, I found myself in need of the following:
[AttributeUsage(AttributeTargets.Field, AllowMultiple = true)]
internal class AliasAttribute : Attribute
{
public AliasAttribute(string text) => Text = text;
public string Text { get; set; }
}
public enum Direction
{
[Alias("^")]
[Alias("N")]
North,
[Alias("v")]
[Alias("S")]
South
}
var aliasFormat = Enums.RegisterCustomEnumFormat(x => x.Attributes.Get<AliasAttribute>()?.Text);
var direction = Enums.Parse<Direction>("N", ignoreCase: true, aliasFormat);
The above fails with "'string was not recognized as being a member of Direction (Parameter 'value')'" because it will only work with the value of the first attribute on each field. I'm wondering whether I'm missing a clever trick with the Enums.RegisterCustomEnumFormat
command. But even with a single refactored AliasAttribute
per field that could store multiple values (eg. [Alias("N", "^")]
), I wouldn't know how to achieve my goal...
EnumFormat
s support parsing and outputting. If they were allowed to support multiple values for parsing Enums.NET would not know what version for outputting with the AsString
method. I'd suggest you create multiple custom enum formats for up to how many alias's you need to support so something like this.
var aliasFormat1 = Enums.RegisterCustomEnumFormat(x => x.Attributes.GetAll<AliasAttribute>().FirstOrDefault()?.Text);
var aliasFormat2 = Enums.RegisterCustomEnumFormat(x => x.Attributes.GetAll<AliasAttribute>().Skip(1).FirstOrDefault()?.Text);
var direction = Enums.Parse<Direction>("N", ignoreCase: true, aliasFormat1, aliasFormat2);
Ah, I hadn't thought of the ambiguity with AsString
. But of course, the same can be said about the current parsing behavior which only considers the first attribute to do its job.
Forgive me for running my imagination, but could this short-hand work?
public static EnumFormat RegisterCustomEnumFormat<T>(Func<T, string> textResolver) where T: Attribute
It would apply to every EnumMember
when parsing, and could easily support multiple attributes.
My first example would be:
var aliasFormat = Enums.RegisterCustomEnumFormat<AliasAttribute>(x => x.Text); // NOTE: unsupported syntax
var direction = Enums.Parse<Direction>("N", ignoreCase: true, aliasFormat); // Evaluates to 'North'
var txt = direction.AsString(aliasFormat); // Evaluates to '^' (first match)
Either way, thanks for suggesting the work-around.