Reputation: 447
I was trying to store and retrieve additional information from enums. I ended up with 2 methods for it. The first method is by using custom attributes. https://stackoverflow.com/a/22054994/5078531 https://stackoverflow.com/a/35040378/5078531
public class DayAttribute : Attribute
{
public string Name { get; private set; }
public DayAttribute(string name)
{
this.Name = name;
}
}
enum Days
{
[Day("Saturday")]
Sat,
[Day("Sunday")]
Sun
}
public static TAttribute GetAttribute<TAttribute>(this Enum value)
where TAttribute : Attribute
{
var enumType = value.GetType();
var name = Enum.GetName(enumType, value);
return enumType.GetField(name).GetCustomAttributes(false).OfType<TAttribute>().SingleOrDefault();
}
The second method I found here, by writing an extension method on enums. https://stackoverflow.com/a/680515/5078531
public enum ArrowDirection
{
North,
South,
East,
West
}
public static class ArrowDirectionExtensions
{
public static UnitVector UnitVector(this ArrowDirection self)
{
switch(self)
{
case ArrowDirection.North:
return new UnitVector(0, 1);
case ArrowDirection.South:
return new UnitVector(0, -1);
case ArrowDirection.East:
return new UnitVector(1, 0);
case ArrowDirection.West:
return new UnitVector(-1, 0);
default:
return null;
}
}
}
If am looking for the performance which method should I choose ? or is there any other efficient methods which am missing?
Upvotes: 3
Views: 217
Reputation: 633
You can make DayaAttributeCache more generic if you like such that it can store other enum and attribute types. I just did this quick to show a caching approach. Enum values have to be continuous starting at 0 but this can be changed to handle that case if needed.
public static class DaysAttributeCache
{
private static readonly string[] Cache;
static DaysAttributeCache()
{
Type enumType = typeof(Days);
Cache = new string[Enum.GetValues(enumType).Length];
foreach (Enum value in Enum.GetValues(enumType))
{
var name = Days.GetName(enumType, value);
DayAttribute attribute = enumType
.GetField(name)
.GetCustomAttributes(false)
.OfType<DayAttribute>()
.SingleOrDefault();
string weekDay = attribute?.Name;
Cache[((IConvertible)value).ToInt32(CultureInfo.InvariantCulture)] = weekDay;
}
}
public static string GetWeekday(this Days value)
{
return Cache[(int)value];
}
}
Called like this...
string saturday = Days.Sat.GetWeekday();
Upvotes: 0
Reputation: 1062790
Both are valid ways of implementing it; as are many other ways. Personally, I like the convenience of the first. The performance penalty of reflection can be mitigated by processing the attributes once only, and storing (presumably in a static
field) - potentially as a flat array if the enum values are contiguous and 0-based; otherwise, perhaps in a dictionary.
Upvotes: 3