Enum<E>
public struct Enum<E> : IEquatable<E>, IComparable<E>, IFormattable, IEquatable<Enum<E>>, ISerializable where E : struct, Enum
Provides strongly typed way to reflect enum type.
using DotNext.Runtime;
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
namespace DotNext
{
[Serializable]
public readonly struct Enum<E> : IEquatable<E>, IComparable<E>, IFormattable, IEquatable<Enum<E>>, ISerializable where E : struct, Enum
{
private readonly struct Tuple : IEquatable<Tuple>
{
internal readonly string Name;
internal readonly E Value;
private Tuple(string name)
{
Name = name;
Value = default(E);
}
private Tuple(E value)
{
Value = value;
Name = null;
}
public static implicit operator Tuple(string name)
{
return new Tuple(name);
}
public static implicit operator Tuple(E value)
{
return new Tuple(value);
}
public bool Equals(Tuple other)
{
if (Name != null)
return Name == other.Name;
if (other.Name == null)
return EqualityComparer<E>.Default.Equals(Value, other.Value);
return false;
}
public override bool Equals(object other)
{
if (other is Tuple) {
Tuple other2 = (Tuple)other;
return Equals(other2);
}
return false;
}
public override int GetHashCode()
{
if (Name != null)
return Name.GetHashCode();
return Value.GetHashCode();
}
}
private sealed class Mapping : Dictionary<Tuple, long>
{
internal readonly Enum<E>[] Members;
internal Enum<E> this[string name] {
get {
return Members[base[name]];
}
}
internal Mapping(out Enum<E> min, out Enum<E> max)
{
string[] names = Enum.GetNames(typeof(E));
E[] array = (E[])Enum.GetValues(typeof(E));
Members = new Enum<E>[names.LongLength];
min = (max = default(Enum<E>));
for (long num = 0; num < names.LongLength; num++) {
Enum<E> enum = Members[num] = new Enum<E>(array[num], names[num]);
Add(enum.Name, num);
base[enum.Value] = num;
E value = enum.Value;
min = ((value.CompareTo(min.Value) < 0) ? enum : min);
value = enum.Value;
max = ((value.CompareTo(max.Value) > 0) ? enum : max);
}
}
internal bool TryGetValue(E value, out Enum<E> member)
{
if (TryGetValue(value, out long value2)) {
member = Members[value2];
return true;
}
member = default(Enum<E>);
return false;
}
}
private static readonly Mapping mapping = new Mapping(out MinValue, out MaxValue);
public static readonly Enum<E> MaxValue;
public static readonly Enum<E> MinValue;
private const string NameSerData = "Name";
private const string ValueSerData = "Value";
private readonly string name;
public static IReadOnlyList<Enum<E>> Members => mapping.Members;
public static Type UnderlyingType => Enum.GetUnderlyingType(typeof(E));
public static TypeCode UnderlyingTypeCode => Type.GetTypeCode(typeof(E));
public E Value { get; }
public string Name => name ?? ValueTypeExtensions.ToString<E>(Value, (IFormatProvider)null);
public static bool IsDefined(E value)
{
return mapping.ContainsKey(value);
}
public static bool IsDefined(string name)
{
return mapping.ContainsKey(name);
}
public static Enum<E> GetMember(E value)
{
if (!mapping.TryGetValue(value, out Enum<E> member))
return new Enum<E>(value, null);
return member;
}
public static bool TryGetMember(E value, out Enum<E> member)
{
return mapping.TryGetValue(value, out member);
}
public static bool TryGetMember(string name, out Enum<E> member)
{
if (Enum.TryParse<E>(name, out E result)) {
member = new Enum<E>(result, name);
return true;
}
member = default(Enum<E>);
return false;
}
public static Enum<E> GetMember(string name)
{
return mapping[name];
}
private Enum(E value, string name)
{
Value = value;
this.name = name;
}
private Enum(SerializationInfo info, StreamingContext context)
{
name = info.GetString("Name");
Value = (E)info.GetValue("Value", typeof(E));
}
public bool HasFlag(E flag)
{
return Intrinsics.HasFlag<E>(Value, flag);
}
public static implicit operator E([In] [System.Runtime.CompilerServices.IsReadOnly] ref Enum<E> en)
{
return en.Value;
}
public int CompareTo(E other)
{
return Comparer<E>.Default.Compare(Value, other);
}
public bool Equals(E other)
{
return EqualityComparer<E>.Default.Equals(Value, other);
}
public bool Equals(Enum<E> other)
{
if (Equals(other.Value))
return object.Equals(Name, other.Name);
return false;
}
public override bool Equals(object other)
{
if (other is Enum<E>) {
Enum<E> other2 = (Enum<E>)other;
return Equals(other2);
}
if (other is E) {
E other3 = (E)other;
return Equals(other3);
}
return false;
}
public override int GetHashCode()
{
return (-1670801664 * -1521134295 + Value.GetHashCode()) * -1521134295 + Name.GetHashCode();
}
public override string ToString()
{
return ValueTypeExtensions.ToString<E>(Value, (IFormatProvider)null);
}
string IFormattable.ToString(string format, IFormatProvider provider)
{
return ValueTypeExtensions.ToString<E>(Value, format, provider);
}
public static bool operator ==(Enum<E> first, Enum<E> second)
{
return first.Equals(second);
}
public static bool operator !=(Enum<E> first, Enum<E> second)
{
return !first.Equals(second);
}
void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("Name", name, typeof(string));
info.AddValue("Value", Value);
}
}
}