Created
January 23, 2019 11:18
-
-
Save Archomeda/293c5c5a5edeceaba810a076a9a35f09 to your computer and use it in GitHub Desktop.
Class to bind attribute properties to enums (C#)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
namespace ClassLibrary1 | |
{ | |
/// <summary> | |
/// A class for binding properties to enums, implemented as custom attributes. | |
/// </summary> | |
/// <typeparam name="TEnum">The enum type.</typeparam> | |
/// <typeparam name="TAttribute">The attribute type.</typeparam> | |
public abstract class EnumWithProperties<TEnum, TAttribute> | |
where TEnum : Enum | |
where TAttribute : Attribute | |
{ | |
private static Dictionary<TEnum, TAttribute> cache = new Dictionary<TEnum, TAttribute>(); | |
/// <summary> | |
/// Initializes a new instance of the <see cref="EnumWithProperties{TEnum, TAttribute}"/> class. | |
/// </summary> | |
/// <param name="enum">The enum.</param> | |
/// <exception cref="ArgumentException">Thrown if the provided enum value is unsupported.</exception> | |
protected EnumWithProperties(TEnum @enum) | |
{ | |
Value = @enum; | |
if (!cache.TryGetValue(@enum, out var attribute)) | |
throw new ArgumentException($"Unsupported enum value '{@enum}' for enum type '{typeof(TEnum).Name}'", nameof(@enum)); | |
AttributeData = attribute; | |
} | |
/// <summary> | |
/// Gets the enum value. | |
/// </summary> | |
public TEnum Value { get; } | |
/// <summary> | |
/// Gets the attribute data. | |
/// </summary> | |
protected TAttribute AttributeData { get; } | |
static EnumWithProperties() | |
{ | |
// Use reflection to dynamically get the enum attributes. | |
// This uses reflection, which is slow, so we need to cache them to speed things up. | |
var enums = Enum.GetValues(typeof(TEnum)).Cast<TEnum>(); | |
foreach (var @enum in enums) | |
{ | |
var member = typeof(TEnum).GetMember(typeof(TEnum).GetEnumName(@enum)); | |
var attribute = member.FirstOrDefault()? | |
.GetCustomAttributes(typeof(TAttribute), false) | |
.FirstOrDefault() as TAttribute; | |
if (attribute != null) | |
cache[@enum] = attribute; | |
} | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
namespace ClassLibrary1 | |
{ | |
public enum EExample | |
{ | |
[Example("Id1")] | |
Value1 = 1, | |
[Example("Id2")] | |
Value2 = 2, | |
[Example("Id3")] | |
Value3 = 3, | |
[Example("Id4")] | |
Value4 = 4 | |
// Add new values here | |
} | |
public class Example : EnumWithProperties<EExample, ExampleAttribute> | |
{ | |
public Example(EExample @enum) : base(@enum) | |
{ | |
Id = AttributeData.Id; | |
} | |
public string Id { get; } | |
} | |
public class ExampleAttribute : Attribute | |
{ | |
public ExampleAttribute(string id) | |
{ | |
Id = id; | |
} | |
public string Id { get; set; } | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment