// ==++== // // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== using System.Reflection; using System.Text; using System.Collections; using System.Globalization; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Diagnostics.Contracts; namespace System { [Serializable] [System.Runtime.InteropServices.ComVisible(true)] public abstract class Enum : ValueType, IComparable, IFormattable, IConvertible { #region Private Static Data Members private static readonly char [] enumSeperatorCharArray = new char [] {','}; private const String enumSeperator = ", "; #endregion #region Private Static Methods [System.Security.SecuritySafeCritical] // auto-generated private static ValuesAndNames GetCachedValuesAndNames(RuntimeType enumType, bool getNames) { ValuesAndNames entry = enumType.GenericCache as ValuesAndNames; if (entry == null || (getNames && entry.Names == null)) { ulong[] values = null; String[] names = null; #if MONO if (!GetEnumValuesAndNames (enumType, out values, out names)) Array.Sort (values, names, System.Collections.Generic.Comparer.Default); #else GetEnumValuesAndNames( enumType.GetTypeHandleInternal(), JitHelpers.GetObjectHandleOnStack(ref values), JitHelpers.GetObjectHandleOnStack(ref names), getNames); #endif entry = new ValuesAndNames(values, names); enumType.GenericCache = entry; } return entry; } private static String InternalFormattedHexString(Object value) { TypeCode typeCode = Convert.GetTypeCode(value); switch (typeCode) { case TypeCode.SByte : { Byte result = (byte)(sbyte)value; return result.ToString("X2", null); } case TypeCode.Byte : { Byte result = (byte)value; return result.ToString("X2", null); } case TypeCode.Boolean: { // direct cast from bool to byte is not allowed Byte result = Convert.ToByte((bool)value); return result.ToString("X2", null); } case TypeCode.Int16: { UInt16 result = (UInt16)(Int16)value; return result.ToString("X4", null); } case TypeCode.UInt16 : { UInt16 result = (UInt16)value; return result.ToString("X4", null); } case TypeCode.Char: { UInt16 result = (UInt16)(Char)value; return result.ToString("X4", null); } case TypeCode.UInt32: { UInt32 result = (UInt32)value; return result.ToString("X8", null); } case TypeCode.Int32 : { UInt32 result = (UInt32)(int)value; return result.ToString("X8", null); } case TypeCode.UInt64 : { UInt64 result = (UInt64)value; return result.ToString("X16", null); } case TypeCode.Int64 : { UInt64 result = (UInt64)(Int64)value; return result.ToString("X16", null); } // All unsigned types will be directly cast default : Contract.Assert(false, "Invalid Object type in Format"); throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_UnknownEnumType")); } } private static String InternalFormat(RuntimeType eT, Object value) { Contract.Requires(eT != null); Contract.Requires(value != null); if (!eT.IsDefined(typeof(System.FlagsAttribute), false)) // Not marked with Flags attribute { // Try to see if its one of the enum values, then we return a String back else the value String retval = GetName(eT, value); if (retval == null) return value.ToString(); else return retval; } else // These are flags OR'ed together (We treat everything as unsigned types) { return InternalFlagsFormat(eT, value); } } private static String InternalFlagsFormat(RuntimeType eT, Object value) { Contract.Requires(eT != null); Contract.Requires(value != null); ulong result = ToUInt64(value); // These values are sorted by value. Don't change this ValuesAndNames entry = GetCachedValuesAndNames(eT, true); String[] names = entry.Names; ulong[] values = entry.Values; Contract.Assert(names.Length == values.Length); int index = values.Length - 1; StringBuilder retval = new StringBuilder(); bool firstTime = true; ulong saveResult = result; // We will not optimize this code further to keep it maintainable. There are some boundary checks that can be applied // to minimize the comparsions required. This code works the same for the best/worst case. In general the number of // items in an enum are sufficiently small and not worth the optimization. while (index >= 0) { if ((index == 0) && (values[index] == 0)) break; if ((result & values[index]) == values[index]) { result -= values[index]; if (!firstTime) retval.Insert(0, enumSeperator); retval.Insert(0, names[index]); firstTime = false; } index--; } // We were unable to represent this number as a bitwise or of valid flags if (result != 0) return value.ToString(); // For the case when we have zero if (saveResult==0) { if (values.Length > 0 && values[0] == 0) return names[0]; // Zero was one of the enum values. else return "0"; } else return retval.ToString(); // Return the string representation } internal static ulong ToUInt64(Object value) { // Helper function to silently convert the value to UInt64 from the other base types for enum without throwing an exception. // This is need since the Convert functions do overflow checks. TypeCode typeCode = Convert.GetTypeCode(value); ulong result; switch(typeCode) { case TypeCode.SByte: case TypeCode.Int16: case TypeCode.Int32: case TypeCode.Int64: result = (UInt64)Convert.ToInt64(value, CultureInfo.InvariantCulture); break; case TypeCode.Byte: case TypeCode.UInt16: case TypeCode.UInt32: case TypeCode.UInt64: case TypeCode.Boolean: case TypeCode.Char: result = Convert.ToUInt64(value, CultureInfo.InvariantCulture); break; default: // All unsigned types will be directly cast Contract.Assert(false, "Invalid Object type in ToUInt64"); throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_UnknownEnumType")); } return result; } #if !MONO [System.Security.SecurityCritical] // auto-generated [ResourceExposure(ResourceScope.None)] #endif [MethodImplAttribute(MethodImplOptions.InternalCall)] private static extern int InternalCompareTo(Object o1, Object o2); #if !MONO [System.Security.SecuritySafeCritical] [ResourceExposure(ResourceScope.None)] #endif [MethodImplAttribute(MethodImplOptions.InternalCall)] internal static extern RuntimeType InternalGetUnderlyingType(RuntimeType enumType); #if MONO [MethodImplAttribute(MethodImplOptions.InternalCall)] private static extern bool GetEnumValuesAndNames (RuntimeType enumType, out ulong[] values, out string[] names); #else [System.Security.SecurityCritical] // auto-generated [ResourceExposure(ResourceScope.None)] [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] [System.Security.SuppressUnmanagedCodeSecurity] private static extern void GetEnumValuesAndNames(RuntimeTypeHandle enumType, ObjectHandleOnStack values, ObjectHandleOnStack names, bool getNames); #endif #if !MONO [System.Security.SecurityCritical] // auto-generated [ResourceExposure(ResourceScope.None)] #endif [MethodImplAttribute(MethodImplOptions.InternalCall)] private static extern Object InternalBoxEnum(RuntimeType enumType, long value); #endregion #region Public Static Methods private enum ParseFailureKind { None = 0, Argument = 1, ArgumentNull = 2, ArgumentWithParameter = 3, UnhandledException = 4 } // This will store the result of the parsing. private struct EnumResult { internal object parsedEnum; internal bool canThrow; internal ParseFailureKind m_failure; internal string m_failureMessageID; internal string m_failureParameter; internal object m_failureMessageFormatArgument; internal Exception m_innerException; internal void Init(bool canMethodThrow) { parsedEnum = 0; canThrow = canMethodThrow; } internal void SetFailure(Exception unhandledException) { m_failure = ParseFailureKind.UnhandledException; m_innerException = unhandledException; } internal void SetFailure(ParseFailureKind failure, string failureParameter) { m_failure = failure; m_failureParameter = failureParameter; if (canThrow) throw GetEnumParseException(); } internal void SetFailure(ParseFailureKind failure, string failureMessageID, object failureMessageFormatArgument) { m_failure = failure; m_failureMessageID = failureMessageID; m_failureMessageFormatArgument = failureMessageFormatArgument; if (canThrow) throw GetEnumParseException(); } internal Exception GetEnumParseException() { switch (m_failure) { case ParseFailureKind.Argument: return new ArgumentException(Environment.GetResourceString(m_failureMessageID)); case ParseFailureKind.ArgumentNull: return new ArgumentNullException(m_failureParameter); case ParseFailureKind.ArgumentWithParameter: return new ArgumentException(Environment.GetResourceString(m_failureMessageID, m_failureMessageFormatArgument)); case ParseFailureKind.UnhandledException: return m_innerException; default: Contract.Assert(false, "Unknown EnumParseFailure: " + m_failure); return new ArgumentException(Environment.GetResourceString("Arg_EnumValueNotFound")); } } } public static bool TryParse(String value, out TEnum result) where TEnum : struct { return TryParse(value, false, out result); } public static bool TryParse(String value, bool ignoreCase, out TEnum result) where TEnum : struct { result = default(TEnum); EnumResult parseResult = new EnumResult(); parseResult.Init(false); bool retValue; if (retValue = TryParseEnum(typeof(TEnum), value, ignoreCase, ref parseResult)) result = (TEnum)parseResult.parsedEnum; return retValue; } [System.Runtime.InteropServices.ComVisible(true)] public static Object Parse(Type enumType, String value) { return Parse(enumType, value, false); } [System.Runtime.InteropServices.ComVisible(true)] public static Object Parse(Type enumType, String value, bool ignoreCase) { EnumResult parseResult = new EnumResult(); parseResult.Init(true); if (TryParseEnum(enumType, value, ignoreCase, ref parseResult)) return parseResult.parsedEnum; else throw parseResult.GetEnumParseException(); } private static bool TryParseEnum(Type enumType, String value, bool ignoreCase, ref EnumResult parseResult) { if (enumType == null) throw new ArgumentNullException("enumType"); Contract.EndContractBlock(); RuntimeType rtType = enumType as RuntimeType; if (rtType == null) throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"), "enumType"); if (!enumType.IsEnum) throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnum"), "enumType"); if (value == null) { parseResult.SetFailure(ParseFailureKind.ArgumentNull, "value"); return false; } value = value.Trim(); if (value.Length == 0) { parseResult.SetFailure(ParseFailureKind.Argument, "Arg_MustContainEnumInfo", null); return false; } // We have 2 code paths here. One if they are values else if they are Strings. // values will have the first character as as number or a sign. ulong result = 0; if (Char.IsDigit(value[0]) || value[0] == '-' || value[0] == '+') { Type underlyingType = GetUnderlyingType(enumType); Object temp; try { temp = Convert.ChangeType(value, underlyingType, CultureInfo.InvariantCulture); parseResult.parsedEnum = ToObject(enumType, temp); return true; } catch (FormatException) { // We need to Parse this as a String instead. There are cases // when you tlbimp enums that can have values of the form "3D". // Don't fix this code. } catch (Exception ex) { if (parseResult.canThrow) throw; else { parseResult.SetFailure(ex); return false; } } } String[] values = value.Split(enumSeperatorCharArray); // Find the field.Lets assume that these are always static classes because the class is // an enum. ValuesAndNames entry = GetCachedValuesAndNames(rtType, true); String[] enumNames = entry.Names; ulong[] enumValues = entry.Values; for (int i = 0; i < values.Length; i++) { values[i] = values[i].Trim(); // We need to remove whitespace characters bool success = false; for (int j = 0; j < enumNames.Length; j++) { if (ignoreCase) { if (String.Compare(enumNames[j], values[i], StringComparison.OrdinalIgnoreCase) != 0) continue; } else { if (!enumNames[j].Equals(values[i])) continue; } ulong item = enumValues[j]; result |= item; success = true; break; } if (!success) { // Not found, throw an argument exception. parseResult.SetFailure(ParseFailureKind.ArgumentWithParameter, "Arg_EnumValueNotFound", value); return false; } } try { parseResult.parsedEnum = ToObject(enumType, result); return true; } catch (Exception ex) { if (parseResult.canThrow) throw; else { parseResult.SetFailure(ex); return false; } } } [System.Runtime.InteropServices.ComVisible(true)] public static Type GetUnderlyingType(Type enumType) { if (enumType == null) throw new ArgumentNullException("enumType"); Contract.Ensures(Contract.Result() != null); Contract.EndContractBlock(); return enumType.GetEnumUnderlyingType(); } [System.Runtime.InteropServices.ComVisible(true)] public static Array GetValues(Type enumType) { if (enumType == null) throw new ArgumentNullException("enumType"); Contract.Ensures(Contract.Result() != null); Contract.EndContractBlock(); return enumType.GetEnumValues(); } internal static ulong[] InternalGetValues(RuntimeType enumType) { // Get all of the values return GetCachedValuesAndNames(enumType, false).Values; } [System.Runtime.InteropServices.ComVisible(true)] public static String GetName(Type enumType, Object value) { if (enumType == null) throw new ArgumentNullException("enumType"); Contract.EndContractBlock(); return enumType.GetEnumName(value); } [System.Runtime.InteropServices.ComVisible(true)] public static String[] GetNames(Type enumType) { if (enumType == null) throw new ArgumentNullException("enumType"); Contract.Ensures(Contract.Result() != null); Contract.EndContractBlock(); return enumType.GetEnumNames(); } internal static String[] InternalGetNames(RuntimeType enumType) { // Get all of the names return GetCachedValuesAndNames(enumType, true).Names; } [System.Runtime.InteropServices.ComVisible(true)] public static Object ToObject(Type enumType, Object value) { if (value == null) throw new ArgumentNullException("value"); Contract.EndContractBlock(); // Delegate rest of error checking to the other functions TypeCode typeCode = Convert.GetTypeCode(value); #if !MONO // NetCF doesn't support char and boolean conversion if (CompatibilitySwitches.IsAppEarlierThanWindowsPhone8 && ((typeCode == TypeCode.Boolean) || (typeCode == TypeCode.Char))) { throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnumBaseTypeOrEnum"), "value"); } #endif switch (typeCode) { case TypeCode.Int32 : return ToObject(enumType, (int)value); case TypeCode.SByte : return ToObject(enumType, (sbyte)value); case TypeCode.Int16 : return ToObject(enumType, (short)value); case TypeCode.Int64 : return ToObject(enumType, (long)value); case TypeCode.UInt32 : return ToObject(enumType, (uint)value); case TypeCode.Byte : return ToObject(enumType, (byte)value); case TypeCode.UInt16 : return ToObject(enumType, (ushort)value); case TypeCode.UInt64 : return ToObject(enumType, (ulong)value); case TypeCode.Char: return ToObject(enumType, (char)value); case TypeCode.Boolean: return ToObject(enumType, (bool)value); default: // All unsigned types will be directly cast throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnumBaseTypeOrEnum"), "value"); } } [Pure] [System.Runtime.InteropServices.ComVisible(true)] public static bool IsDefined(Type enumType, Object value) { if (enumType == null) throw new ArgumentNullException("enumType"); Contract.EndContractBlock(); return enumType.IsEnumDefined(value); } [System.Runtime.InteropServices.ComVisible(true)] public static String Format(Type enumType, Object value, String format) { if (enumType == null) throw new ArgumentNullException("enumType"); if (!enumType.IsEnum) throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnum"), "enumType"); if (value == null) throw new ArgumentNullException("value"); if (format == null) throw new ArgumentNullException("format"); Contract.EndContractBlock(); RuntimeType rtType = enumType as RuntimeType; if (rtType == null) throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"), "enumType"); // Check if both of them are of the same type Type valueType = value.GetType(); Type underlyingType = GetUnderlyingType(enumType); // If the value is an Enum then we need to extract the underlying value from it if (valueType.IsEnum) { Type valueUnderlyingType = GetUnderlyingType(valueType); if (!valueType.IsEquivalentTo(enumType)) throw new ArgumentException(Environment.GetResourceString("Arg_EnumAndObjectMustBeSameType", valueType.ToString(), enumType.ToString())); valueType = valueUnderlyingType; value = ((Enum)value).GetValue(); } // The value must be of the same type as the Underlying type of the Enum else if (valueType != underlyingType) { throw new ArgumentException(Environment.GetResourceString("Arg_EnumFormatUnderlyingTypeAndObjectMustBeSameType", valueType.ToString(), underlyingType.ToString())); } if( format.Length != 1) { // all acceptable format string are of length 1 throw new FormatException(Environment.GetResourceString("Format_InvalidEnumFormatSpecification")); } char formatCh = format[0]; if (formatCh == 'D' || formatCh == 'd') { return value.ToString(); } if (formatCh == 'X' || formatCh == 'x') { // Retrieve the value from the field. return InternalFormattedHexString(value); } if (formatCh == 'G' || formatCh == 'g') { return InternalFormat(rtType, value); } if (formatCh == 'F' || formatCh == 'f') { return InternalFlagsFormat(rtType, value); } throw new FormatException(Environment.GetResourceString("Format_InvalidEnumFormatSpecification")); } #endregion #region Definitions private class ValuesAndNames { // Each entry contains a list of sorted pair of enum field names and values, sorted by values public ValuesAndNames(ulong[] values, String[] names) { this.Values = values; this.Names = names; } public ulong[] Values; public String[] Names; } #endregion #if MONO [MethodImplAttribute (MethodImplOptions.InternalCall)] extern object get_value (); #endif #region Private Methods [System.Security.SecuritySafeCritical] internal unsafe Object GetValue() { #if MONO return get_value (); #else fixed (void* pValue = &JitHelpers.GetPinningHelper(this).m_data) { switch (InternalGetCorElementType()) { case CorElementType.I1: return *(sbyte*)pValue; case CorElementType.U1: return *(byte*)pValue; case CorElementType.Boolean: return *(bool*)pValue; case CorElementType.I2: return *(short*)pValue; case CorElementType.U2: return *(ushort*)pValue; case CorElementType.Char: return *(char*)pValue; case CorElementType.I4: return *(int*)pValue; case CorElementType.U4: return *(uint*)pValue; case CorElementType.R4: return *(float*)pValue; case CorElementType.I8: return *(long*)pValue; case CorElementType.U8: return *(ulong*)pValue; case CorElementType.R8: return *(double*)pValue; case CorElementType.I: return *(IntPtr*)pValue; case CorElementType.U: return *(UIntPtr*)pValue; default: Contract.Assert(false, "Invalid primitive type"); return null; } } #endif } #if !MONO [System.Security.SecurityCritical] // auto-generated [ResourceExposure(ResourceScope.None)] #endif [MethodImplAttribute(MethodImplOptions.InternalCall)] private extern bool InternalHasFlag(Enum flags); [MethodImplAttribute(MethodImplOptions.InternalCall)] #if MONO private extern int get_hashcode (); #else [System.Security.SecuritySafeCritical] // auto-generated [ResourceExposure(ResourceScope.None)] private extern CorElementType InternalGetCorElementType(); #endif #endregion #region Object Overrides #if MONO public override bool Equals (object obj) { return DefaultEquals (this, obj); } #else [System.Security.SecuritySafeCritical] // auto-generated [ResourceExposure(ResourceScope.None)] [MethodImplAttribute(MethodImplOptions.InternalCall)] public extern override bool Equals(Object obj); #endif [System.Security.SecuritySafeCritical] public override unsafe int GetHashCode() { #if MONO return get_hashcode (); #else // Avoid boxing by inlining GetValue() // return GetValue().GetHashCode(); fixed (void* pValue = &JitHelpers.GetPinningHelper(this).m_data) { switch (InternalGetCorElementType()) { case CorElementType.I1: return (*(sbyte*)pValue).GetHashCode(); case CorElementType.U1: return (*(byte*)pValue).GetHashCode(); case CorElementType.Boolean: return (*(bool*)pValue).GetHashCode(); case CorElementType.I2: return (*(short*)pValue).GetHashCode(); case CorElementType.U2: return (*(ushort*)pValue).GetHashCode(); case CorElementType.Char: return (*(char*)pValue).GetHashCode(); case CorElementType.I4: return (*(int*)pValue).GetHashCode(); case CorElementType.U4: return (*(uint*)pValue).GetHashCode(); case CorElementType.R4: return (*(float*)pValue).GetHashCode(); case CorElementType.I8: return (*(long*)pValue).GetHashCode(); case CorElementType.U8: return (*(ulong*)pValue).GetHashCode(); case CorElementType.R8: return (*(double*)pValue).GetHashCode(); case CorElementType.I: return (*(IntPtr*)pValue).GetHashCode(); case CorElementType.U: return (*(UIntPtr*)pValue).GetHashCode(); default: Contract.Assert(false, "Invalid primitive type"); return 0; } } #endif } public override String ToString() { // Returns the value in a human readable format. For PASCAL style enums who's value maps directly the name of the field is returned. // For PASCAL style enums who's values do not map directly the decimal value of the field is returned. // For BitFlags (indicated by the Flags custom attribute): If for each bit that is set in the value there is a corresponding constant //(a pure power of 2), then the OR string (ie "Red | Yellow") is returned. Otherwise, if the value is zero or if you can't create a string that consists of // pure powers of 2 OR-ed together, you return a hex value return Enum.InternalFormat((RuntimeType)GetType(), GetValue()); } #endregion #region IFormattable [Obsolete("The provider argument is not used. Please use ToString(String).")] public String ToString(String format, IFormatProvider provider) { return ToString(format); } #endregion #region IComparable [System.Security.SecuritySafeCritical] // auto-generated public int CompareTo(Object target) { const int retIncompatibleMethodTables = 2; // indicates that the method tables did not match const int retInvalidEnumType = 3; // indicates that the enum was of an unknown/unsupported unerlying type if (this == null) throw new NullReferenceException(); Contract.EndContractBlock(); int ret = InternalCompareTo(this, target); if (ret < retIncompatibleMethodTables) { // -1, 0 and 1 are the normal return codes return ret; } else if (ret == retIncompatibleMethodTables) { Type thisType = this.GetType(); Type targetType = target.GetType(); throw new ArgumentException(Environment.GetResourceString("Arg_EnumAndObjectMustBeSameType", targetType.ToString(), thisType.ToString())); } else { // assert valid return code (3) Contract.Assert(ret == retInvalidEnumType, "Enum.InternalCompareTo return code was invalid"); throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_UnknownEnumType")); } } #endregion #region Public Methods public String ToString(String format) { if (format == null || format.Length == 0) format = "G"; if (String.Compare(format, "G", StringComparison.OrdinalIgnoreCase) == 0) return ToString(); if (String.Compare(format, "D", StringComparison.OrdinalIgnoreCase) == 0) return GetValue().ToString(); if (String.Compare(format, "X", StringComparison.OrdinalIgnoreCase) == 0) return InternalFormattedHexString(GetValue()); if (String.Compare(format, "F", StringComparison.OrdinalIgnoreCase) == 0) return InternalFlagsFormat((RuntimeType)GetType(), GetValue()); throw new FormatException(Environment.GetResourceString("Format_InvalidEnumFormatSpecification")); } [Obsolete("The provider argument is not used. Please use ToString().")] public String ToString(IFormatProvider provider) { return ToString(); } [System.Security.SecuritySafeCritical] public Boolean HasFlag(Enum flag) { if (flag == null) throw new ArgumentNullException("flag"); Contract.EndContractBlock(); if (!this.GetType().IsEquivalentTo(flag.GetType())) { throw new ArgumentException(Environment.GetResourceString("Argument_EnumTypeDoesNotMatch", flag.GetType(), this.GetType())); } return InternalHasFlag(flag); } #endregion #region IConvertable public TypeCode GetTypeCode() { Type enumType = this.GetType(); Type underlyingType = GetUnderlyingType(enumType); if (underlyingType == typeof(Int32)) { return TypeCode.Int32; } if (underlyingType == typeof(sbyte)) { return TypeCode.SByte; } if (underlyingType == typeof(Int16)) { return TypeCode.Int16; } if (underlyingType == typeof(Int64)) { return TypeCode.Int64; } if (underlyingType == typeof(UInt32)) { return TypeCode.UInt32; } if (underlyingType == typeof(byte)) { return TypeCode.Byte; } if (underlyingType == typeof(UInt16)) { return TypeCode.UInt16; } if (underlyingType == typeof(UInt64)) { return TypeCode.UInt64; } if (underlyingType == typeof(Boolean)) { return TypeCode.Boolean; } if (underlyingType == typeof(Char)) { return TypeCode.Char; } Contract.Assert(false, "Unknown underlying type."); throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_UnknownEnumType")); } /// bool IConvertible.ToBoolean(IFormatProvider provider) { return Convert.ToBoolean(GetValue(), CultureInfo.CurrentCulture); } /// char IConvertible.ToChar(IFormatProvider provider) { return Convert.ToChar(GetValue(), CultureInfo.CurrentCulture); } /// sbyte IConvertible.ToSByte(IFormatProvider provider) { return Convert.ToSByte(GetValue(), CultureInfo.CurrentCulture); } /// byte IConvertible.ToByte(IFormatProvider provider) { return Convert.ToByte(GetValue(), CultureInfo.CurrentCulture); } /// short IConvertible.ToInt16(IFormatProvider provider) { return Convert.ToInt16(GetValue(), CultureInfo.CurrentCulture); } /// ushort IConvertible.ToUInt16(IFormatProvider provider) { return Convert.ToUInt16(GetValue(), CultureInfo.CurrentCulture); } /// int IConvertible.ToInt32(IFormatProvider provider) { return Convert.ToInt32(GetValue(), CultureInfo.CurrentCulture); } /// uint IConvertible.ToUInt32(IFormatProvider provider) { return Convert.ToUInt32(GetValue(), CultureInfo.CurrentCulture); } /// long IConvertible.ToInt64(IFormatProvider provider) { return Convert.ToInt64(GetValue(), CultureInfo.CurrentCulture); } /// ulong IConvertible.ToUInt64(IFormatProvider provider) { return Convert.ToUInt64(GetValue(), CultureInfo.CurrentCulture); } /// float IConvertible.ToSingle(IFormatProvider provider) { return Convert.ToSingle(GetValue(), CultureInfo.CurrentCulture); } /// double IConvertible.ToDouble(IFormatProvider provider) { return Convert.ToDouble(GetValue(), CultureInfo.CurrentCulture); } /// Decimal IConvertible.ToDecimal(IFormatProvider provider) { return Convert.ToDecimal(GetValue(), CultureInfo.CurrentCulture); } /// DateTime IConvertible.ToDateTime(IFormatProvider provider) { throw new InvalidCastException(Environment.GetResourceString("InvalidCast_FromTo", "Enum", "DateTime")); } /// Object IConvertible.ToType(Type type, IFormatProvider provider) { return Convert.DefaultToType((IConvertible)this, type, provider); } #endregion #region ToObject [System.Security.SecuritySafeCritical] // auto-generated [CLSCompliant(false)] [System.Runtime.InteropServices.ComVisible(true)] public static Object ToObject(Type enumType, sbyte value) { if (enumType == null) throw new ArgumentNullException("enumType"); if (!enumType.IsEnum) throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnum"), "enumType"); Contract.EndContractBlock(); RuntimeType rtType = enumType as RuntimeType; if (rtType == null) throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"), "enumType"); return InternalBoxEnum(rtType, value); } [System.Security.SecuritySafeCritical] // auto-generated [System.Runtime.InteropServices.ComVisible(true)] public static Object ToObject(Type enumType, short value) { if (enumType == null) throw new ArgumentNullException("enumType"); if (!enumType.IsEnum) throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnum"), "enumType"); Contract.EndContractBlock(); RuntimeType rtType = enumType as RuntimeType; if (rtType == null) throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"), "enumType"); return InternalBoxEnum(rtType, value); } [System.Security.SecuritySafeCritical] // auto-generated [System.Runtime.InteropServices.ComVisible(true)] public static Object ToObject(Type enumType, int value) { if (enumType == null) throw new ArgumentNullException("enumType"); if (!enumType.IsEnum) throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnum"), "enumType"); Contract.EndContractBlock(); RuntimeType rtType = enumType as RuntimeType; if (rtType == null) throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"), "enumType"); return InternalBoxEnum(rtType, value); } [System.Security.SecuritySafeCritical] // auto-generated [System.Runtime.InteropServices.ComVisible(true)] public static Object ToObject(Type enumType, byte value) { if (enumType == null) throw new ArgumentNullException("enumType"); if (!enumType.IsEnum) throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnum"), "enumType"); Contract.EndContractBlock(); RuntimeType rtType = enumType as RuntimeType; if (rtType == null) throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"), "enumType"); return InternalBoxEnum(rtType, value); } [System.Security.SecuritySafeCritical] // auto-generated [CLSCompliant(false)] [System.Runtime.InteropServices.ComVisible(true)] public static Object ToObject(Type enumType, ushort value) { if (enumType == null) throw new ArgumentNullException("enumType"); if (!enumType.IsEnum) throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnum"), "enumType"); Contract.EndContractBlock(); RuntimeType rtType = enumType as RuntimeType; if (rtType == null) throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"), "enumType"); return InternalBoxEnum(rtType, value); } [System.Security.SecuritySafeCritical] // auto-generated [CLSCompliant(false)] [System.Runtime.InteropServices.ComVisible(true)] public static Object ToObject(Type enumType, uint value) { if (enumType == null) throw new ArgumentNullException("enumType"); if (!enumType.IsEnum) throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnum"), "enumType"); Contract.EndContractBlock(); RuntimeType rtType = enumType as RuntimeType; if (rtType == null) throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"), "enumType"); return InternalBoxEnum(rtType, value); } [System.Security.SecuritySafeCritical] // auto-generated [System.Runtime.InteropServices.ComVisible(true)] public static Object ToObject(Type enumType, long value) { if (enumType == null) throw new ArgumentNullException("enumType"); if (!enumType.IsEnum) throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnum"), "enumType"); Contract.EndContractBlock(); RuntimeType rtType = enumType as RuntimeType; if (rtType == null) throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"), "enumType"); return InternalBoxEnum(rtType, value); } [System.Security.SecuritySafeCritical] // auto-generated [CLSCompliant(false)] [System.Runtime.InteropServices.ComVisible(true)] public static Object ToObject(Type enumType, ulong value) { if (enumType == null) throw new ArgumentNullException("enumType"); if (!enumType.IsEnum) throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnum"), "enumType"); Contract.EndContractBlock(); RuntimeType rtType = enumType as RuntimeType; if (rtType == null) throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"), "enumType"); return InternalBoxEnum(rtType, unchecked((long)value)); } [System.Security.SecuritySafeCritical] // auto-generated private static Object ToObject(Type enumType, char value) { if (enumType == null) throw new ArgumentNullException("enumType"); if (!enumType.IsEnum) throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnum"), "enumType"); Contract.EndContractBlock(); RuntimeType rtType = enumType as RuntimeType; if (rtType == null) throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"), "enumType"); return InternalBoxEnum(rtType, value); } [System.Security.SecuritySafeCritical] // auto-generated private static Object ToObject(Type enumType, bool value) { if (enumType == null) throw new ArgumentNullException("enumType"); if (!enumType.IsEnum) throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnum"), "enumType"); Contract.EndContractBlock(); RuntimeType rtType = enumType as RuntimeType; if (rtType == null) throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"), "enumType"); return InternalBoxEnum(rtType, value ? 1 : 0); } #endregion #if MONO public static TEnum Parse(string value) where TEnum : struct { return Parse(value, false); } public static TEnum Parse(string value, bool ignoreCase) where TEnum : struct { EnumResult parseResult = new EnumResult() { canThrow = true }; if (TryParseEnum(typeof(TEnum), value, ignoreCase, ref parseResult)) return (TEnum)parseResult.parsedEnum; else throw parseResult.GetEnumParseException(); } public static bool TryParse(Type enumType, String value, bool ignoreCase, out object result) { result = null; EnumResult parseResult = new EnumResult(); bool retValue; if (retValue = TryParseEnum(enumType, value, ignoreCase, ref parseResult)) result = parseResult.parsedEnum; return retValue; } public static bool TryParse(Type enumType, String value, out object result) { return TryParse(enumType, value, false, out result); } #endif } }