Skip to main content
using System.ComponentModel;

namespace System
{
    public class Enum<T>
    {
        public static T Parse(string value)
        {
            return Parse(value, true);
        }

        public static T Parse(string value, bool ignoreCase)
        {
            try
            {
                return (T)Enum.Parse(typeof(T), value, ignoreCase);
            }

            catch (Exception)
            {
                var attrs = TypeDescriptor.GetAttributes(typeof (T));

                foreach (var attr in attrs)
                {
                    DefaultEnumAttribute defEnum = attr as DefaultEnumAttribute;

                    if (defEnum != null)
                        return (T) defEnum.DefaultValue;
                }

                throw;
            }
        }

        public static T Parse(string value, T deflt)
        {
            try
            {
                return Parse(value, true, deflt);
            }
            catch
            {
                return deflt;
            }
        }

        public static T Parse(string value, bool ignoreCase, T deflt)
        {
            try
            {
                if (string.IsNullOrEmpty(value))
                    return deflt;

                return (T)Enum.Parse(typeof(T), value, ignoreCase);
            }
            catch
            {
                return deflt;
            }
        }

        public static T [] GetValues()
        {
            return (T[]) Enum.GetValues(typeof (T));
        }
    }

    [AttributeUsage(AttributeTargets.All, Inherited = false, AllowMultiple = false)]
    public sealed class DefaultEnumAttribute : Attribute
    {
        public DefaultEnumAttribute(object defaultValue)
        {
            DefaultValue = defaultValue;
        }

        public object DefaultValue { get; private set; }
    }
}