From 6cfef20c1524b8d4c1495a652dfe9e898c5a486b Mon Sep 17 00:00:00 2001 From: Stephen Toub Date: Sat, 7 Nov 2020 09:06:22 -0500 Subject: [PATCH] Improve performance of Enum's generic IsDefined / GetName / GetNames (#44355) Eliminates the boxing in IsDefined/GetName/GetValues, and in GetNames avoids having to go through RuntimeType's GetEnumNames override. --- .../System.Private.CoreLib/src/System/Enum.cs | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Enum.cs b/src/libraries/System.Private.CoreLib/src/System/Enum.cs index 38ed61a..d69077c 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Enum.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Enum.cs @@ -258,11 +258,26 @@ namespace System return result; } + private static ulong ToUInt64(TEnum value) where TEnum : struct, Enum => + Type.GetTypeCode(typeof(TEnum)) switch + { + TypeCode.SByte => (ulong)Unsafe.As(ref value), + TypeCode.Byte => Unsafe.As(ref value), + TypeCode.Boolean => Convert.ToByte(Unsafe.As(ref value)), + TypeCode.Int16 => (ulong)Unsafe.As(ref value), + TypeCode.UInt16 => Unsafe.As(ref value), + TypeCode.Char => Unsafe.As(ref value), + TypeCode.UInt32 => Unsafe.As(ref value), + TypeCode.Int32 => (ulong)Unsafe.As(ref value), + TypeCode.UInt64 => Unsafe.As(ref value), + TypeCode.Int64 => (ulong)Unsafe.As(ref value), + _ => throw new InvalidOperationException(SR.InvalidOperation_UnknownEnumType), + }; #endregion #region Public Static Methods public static string? GetName(TEnum value) where TEnum : struct, Enum - => GetName(typeof(TEnum), value); + => GetEnumName((RuntimeType)typeof(TEnum), ToUInt64(value)); public static string? GetName(Type enumType, object value) { @@ -273,7 +288,7 @@ namespace System } public static string[] GetNames() where TEnum : struct, Enum - => GetNames(typeof(TEnum)); + => new ReadOnlySpan(InternalGetNames((RuntimeType)typeof(TEnum))).ToArray(); public static string[] GetNames(Type enumType) { -- 2.7.4