Skip to content

Instantly share code, notes, and snippets.

@kiwipiet
Created July 18, 2016 20:22
Show Gist options
  • Save kiwipiet/28e6ae82296281b667b5bccc26822b28 to your computer and use it in GitHub Desktop.
Save kiwipiet/28e6ae82296281b667b5bccc26822b28 to your computer and use it in GitHub Desktop.
Enumeration class that is PCL compatible
[DataContract]
[DebuggerDisplay("{DisplayName} - {Value}")]
public abstract class Enumeration<TEnumeration> : Enumeration<TEnumeration, int> where TEnumeration : Enumeration<TEnumeration>
{
protected Enumeration(int value, string displayName) : base(value, displayName) { }
public static TEnumeration FromInt32(int value)
{
return FromValue(value);
}
public static bool TryFromInt32(int listItemValue, out TEnumeration result)
{
return TryParse(listItemValue, out result);
}
}
[DataContract]
[DebuggerDisplay("{DisplayName} - {Value}")]
public abstract class Enumeration<TEnumeration, TValue> : IComparable<TEnumeration>, IEquatable<TEnumeration>
where TEnumeration : Enumeration<TEnumeration, TValue>
where TValue : IComparable
{
private static readonly Lazy<TEnumeration[]> Enumerations = new Lazy<TEnumeration[]>(GetEnumerations);
protected Enumeration(TValue value, string displayName)
{
Value = value;
DisplayName = displayName;
}
public TValue Value { get; }
public string DisplayName { get; }
public int CompareTo(TEnumeration other)
{
return Value.CompareTo(other.Value);
}
public sealed override string ToString()
{
return DisplayName;
}
public static TEnumeration[] GetAll()
{
return Enumerations.Value;
}
private static TEnumeration[] GetEnumerations()
{
var enumerationType = typeof(TEnumeration);
var typeInfo = enumerationType.GetTypeInfo();
return enumerationType
.GetRuntimeFields()
.Where(x => x.IsPublic || x.IsStatic)
.Where(info => typeInfo.IsAssignableFrom(info.FieldType.GetTypeInfo()))
.Select(info => info.GetValue(null))
.Cast<TEnumeration>()
.ToArray();
}
public override bool Equals(object obj)
{
return Equals(obj as TEnumeration);
}
public bool Equals(TEnumeration other)
{
return other != null && Value.Equals(other.Value);
}
public override int GetHashCode()
{
return Value.GetHashCode();
}
public static bool operator ==(Enumeration<TEnumeration, TValue> left, Enumeration<TEnumeration, TValue> right)
{
return Equals(left, right);
}
public static bool operator !=(Enumeration<TEnumeration, TValue> left, Enumeration<TEnumeration, TValue> right)
{
return !Equals(left, right);
}
public static TEnumeration FromValueOrNull(TValue value)
{
if (value == null) { return null; }
return Parse(value, "value", item => item.Value.Equals(value));
}
public static TEnumeration FromValueOrNull<T>(T? value) where T : struct, TValue
{
if (value == null) { return null; }
return Parse(value, "value", item => item.Value.Equals(value));
}
public static TEnumeration FromValue(TValue value)
{
return Parse(value, "value", item => item.Value.Equals(value));
}
public static TEnumeration Parse(string displayName)
{
return Parse(displayName, "display name", item => item.DisplayName == displayName);
}
private static bool TryParse(Func<TEnumeration, bool> predicate, out TEnumeration result)
{
result = GetAll().FirstOrDefault(predicate);
return result != null;
}
private static TEnumeration Parse(object value, string description, Func<TEnumeration, bool> predicate)
{
TEnumeration result;
if (!TryParse(predicate, out result))
{
var message = $"'{value}' is not a valid {description} in {typeof(TEnumeration)}";
throw new ArgumentException(message, nameof(value));
}
return result;
}
public static bool TryParse(TValue value, out TEnumeration result)
{
return TryParse(e => e.Value.Equals(value), out result);
}
public static bool TryParse(string displayName, out TEnumeration result)
{
return TryParse(e => e.DisplayName == displayName, out result);
}
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "0")]
public static implicit operator TValue(Enumeration<TEnumeration, TValue> enumValue)
{
return enumValue.Value;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment