diff --git a/src/mscorlib/src/System/Enum.cs b/src/mscorlib/src/System/Enum.cs index e165374c919f..46cce953993d 100644 --- a/src/mscorlib/src/System/Enum.cs +++ b/src/mscorlib/src/System/Enum.cs @@ -388,30 +388,30 @@ private static bool TryParseEnum(Type enumType, String value, bool ignoreCase, r if (Char.IsDigit(value[0]) || value[0] == '-' || value[0] == '+') { - Type underlyingType = GetUnderlyingType(enumType); - Object temp; + bool parseSuccess = TryParseEnumValue(enumType, value, ref result, ref parseResult); - try + if (parseSuccess) { - 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 + try + { + parseResult.parsedEnum = ToObject(enumType, result); + return true; + } + catch (Exception ex) { - parseResult.SetFailure(ex); - return false; + if (parseResult.canThrow) + throw; + else + { + parseResult.SetFailure(ex); + return false; + } } } + else if (parseResult.m_failure != ParseFailureKind.None) + { + return false; + } } String[] values = value.Split(enumSeperatorCharArray); @@ -474,6 +474,112 @@ private static bool TryParseEnum(Type enumType, String value, bool ignoreCase, r } } + private static bool TryParseEnumValue(Type enumType, String value, ref ulong result, ref EnumResult parseResult) + { + switch (Type.GetTypeCode(enumType)) + { + case TypeCode.Boolean: + return false; + + case TypeCode.Char: + { + char temp; + if (Char.TryParse(value, out temp)) + { + result = (ulong)temp; + return true; + } + return false; + } + case TypeCode.Byte: + { + byte temp; + if (Byte.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out temp)) + { + result = (ulong)temp; + return true; + } + return false; + } + case TypeCode.SByte: + { + sbyte temp; + if (SByte.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out temp)) + { + result = (ulong)temp; + return true; + } + return false; + } + case TypeCode.Int16: + { + short temp; + if (Int16.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out temp)) + { + result = (ulong)temp; + return true; + } + return false; + } + case TypeCode.UInt16: + { + ushort temp; + if (UInt16.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out temp)) + { + result = (ulong)temp; + return true; + } + return false; + } + case TypeCode.Int32: + { + int temp; + if (Int32.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out temp)) + { + result = (ulong)temp; + return true; + } + return false; + } + case TypeCode.UInt32: + { + uint temp; + if (UInt32.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out temp)) + { + result = (ulong)temp; + return true; + } + return false; + } + case TypeCode.Int64: + { + long temp; + if (Int64.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out temp)) + { + result = (ulong)temp; + return true; + } + return false; + } + case TypeCode.UInt64: + { + ulong temp; + if (UInt64.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out temp)) + { + result = (ulong)temp; + return true; + } + return false; + } + default: + { + // This is needed for backwards compatibility + parseResult.SetFailure(ParseFailureKind.Argument, "Arg_MustBeEnumBaseTypeOrEnum", null); + return false; + } + } + } + [System.Runtime.InteropServices.ComVisible(true)] public static Type GetUnderlyingType(Type enumType) {