21
21
// * SOFTWARE.
22
22
23
23
using System ;
24
- using System . Collections . Concurrent ;
25
24
using System . Collections . Generic ;
26
25
using System . Reflection ;
27
26
using System . Runtime . Serialization ;
@@ -31,86 +30,97 @@ namespace PuppeteerSharp.Helpers;
31
30
32
31
internal static class EnumHelper
33
32
{
34
- private static readonly ConcurrentDictionary < Type , IReadOnlyDictionary < string , Enum > > _stringToEnumCache = new ( ) ;
33
+ public static string [ ] GetNames < TEnum > ( )
34
+ where TEnum : struct , Enum =>
35
+ #if NET8_0_OR_GREATER
36
+ Enum . GetNames < TEnum > ( ) ;
37
+ #else
38
+ Enum . GetNames ( typeof ( TEnum ) ) ;
39
+ #endif
35
40
36
- private static readonly ConcurrentDictionary < Type , IReadOnlyDictionary < Enum , string > > _enumToStringCache = new ( ) ;
41
+ public static TEnum [ ] GetValues < TEnum > ( )
42
+ where TEnum : struct , Enum =>
43
+ #if NET8_0_OR_GREATER
44
+ Enum . GetValues < TEnum > ( ) ;
45
+ #else
46
+ ( TEnum [ ] ) Enum . GetValues ( typeof ( TEnum ) ) ;
47
+ #endif
37
48
38
- public static TEnum ToEnum < TEnum > ( this string value )
39
- where TEnum : Enum
40
- {
41
- var enumValues = _stringToEnumCache . GetOrAdd ( typeof ( TEnum ) , type =>
42
- {
43
- var names = Enum . GetNames ( type ) ;
44
- var values = ( TEnum [ ] ) Enum . GetValues ( type ) ;
45
- var dictionary = new Dictionary < string , Enum > ( StringComparer . OrdinalIgnoreCase ) ;
46
- for ( var i = 0 ; i < names . Length ; i ++ )
47
- {
48
- dictionary . Add ( names [ i ] , values [ i ] ) ;
49
- var memberValue = type . GetField ( names [ i ] ) . GetCustomAttribute < EnumMemberAttribute > ( ) ? . Value ;
50
- if ( memberValue != null )
51
- {
52
- dictionary [ memberValue ] = values [ i ] ;
53
- }
54
- }
49
+ public static TEnum Parse < TEnum > ( string value , bool ignoreCase )
50
+ where TEnum : struct , Enum =>
51
+ #if NET8_0_OR_GREATER
52
+ Enum . Parse < TEnum > ( value , ignoreCase ) ;
53
+ #else
54
+ ( TEnum ) Enum . Parse ( typeof ( TEnum ) , value , ignoreCase ) ;
55
+ #endif
55
56
56
- return dictionary ;
57
- } ) ;
58
- return ( TEnum ) enumValues [ value ] ;
59
- }
57
+ public static TEnum ToEnum < TEnum > ( this string value )
58
+ where TEnum : struct , Enum
59
+ => StringToEnum < TEnum > . Cache [ value ] ;
60
60
61
61
public static string ToValueString < TEnum > ( this TEnum value )
62
- where TEnum : Enum
62
+ where TEnum : struct , Enum
63
+ => EnumToString < TEnum > . Cache [ value ] ;
64
+
65
+ public static TEnum FromValueString < TEnum > ( string value )
66
+ where TEnum : struct , Enum
63
67
{
64
- var enumValues = _enumToStringCache . GetOrAdd ( typeof ( TEnum ) , type =>
68
+ if ( StringToEnum < TEnum > . Cache . TryGetValue ( value , out var enumValue ) )
65
69
{
66
- var names = Enum . GetNames ( type ) ;
67
- var dictionary = new Dictionary < Enum , string > ( ) ;
68
- foreach ( var t in names )
69
- {
70
- var field = type . GetField ( t ) ;
71
- var valueName = field . GetCustomAttribute < EnumMemberAttribute > ( ) ? . Value ?? t ;
72
- var fieldValue = ( TEnum ) field . GetValue ( null ) ;
73
- dictionary [ fieldValue ] = valueName ;
74
- }
70
+ return enumValue ;
71
+ }
75
72
76
- return dictionary ;
77
- } ) ;
73
+ var defaultEnumAttribute = typeof ( TEnum ) . GetCustomAttribute < DefaultEnumValueAttribute > ( ) ;
74
+ if ( defaultEnumAttribute != null )
75
+ {
76
+ return ( TEnum ) ( object ) defaultEnumAttribute . Value ;
77
+ }
78
78
79
- return enumValues [ value ] ;
79
+ throw new ArgumentException ( $ "Unknown value ' { value } ' for enum { typeof ( TEnum ) . Name } " ) ;
80
80
}
81
81
82
- public static TEnum FromValueString < TEnum > ( string value )
82
+ private static class StringToEnum < TEnum >
83
83
where TEnum : struct , Enum
84
84
{
85
- var enumValues = _stringToEnumCache . GetOrAdd ( typeof ( TEnum ) , type =>
85
+ public static readonly IReadOnlyDictionary < string , TEnum > Cache = Compute ( ) ;
86
+
87
+ private static Dictionary < string , TEnum > Compute ( )
86
88
{
87
- var names = Enum . GetNames ( type ) ;
88
- var dictionary = new Dictionary < string , Enum > ( StringComparer . OrdinalIgnoreCase ) ;
89
- foreach ( var valueName in names )
89
+ var names = GetNames < TEnum > ( ) ;
90
+ var dictionary = new Dictionary < string , TEnum > ( StringComparer . OrdinalIgnoreCase ) ;
91
+ foreach ( var name in names )
90
92
{
91
- var field = type . GetField ( valueName ) ;
93
+ var field = typeof ( TEnum ) . GetField ( name ) ;
92
94
var fieldValue = ( TEnum ) field . GetValue ( null ) ;
93
- dictionary [ valueName ] = fieldValue ;
95
+ dictionary [ name ] = fieldValue ;
94
96
if ( field . GetCustomAttribute < EnumMemberAttribute > ( ) ? . Value is { } enumMember )
95
97
{
96
98
dictionary [ enumMember ] = fieldValue ;
97
99
}
98
100
}
99
101
100
102
return dictionary ;
101
- } ) ;
102
-
103
- if ( enumValues . TryGetValue ( value , out var enumValue ) )
104
- {
105
- return ( TEnum ) enumValue ;
106
103
}
104
+ }
107
105
108
- var defaultEnumAttribute = typeof ( TEnum ) . GetCustomAttribute < DefaultEnumValueAttribute > ( ) ;
109
- if ( defaultEnumAttribute != null )
106
+ private static class EnumToString < TEnum >
107
+ where TEnum : struct , Enum
108
+ {
109
+ public static readonly IReadOnlyDictionary < TEnum , string > Cache = Compute ( ) ;
110
+
111
+ private static Dictionary < TEnum , string > Compute ( )
110
112
{
111
- return ( TEnum ) ( object ) defaultEnumAttribute . Value ;
112
- }
113
+ var names = GetNames < TEnum > ( ) ;
114
+ var dictionary = new Dictionary < TEnum , string > ( ) ;
115
+ foreach ( var name in names )
116
+ {
117
+ var field = typeof ( TEnum ) . GetField ( name ) ;
118
+ var valueName = field . GetCustomAttribute < EnumMemberAttribute > ( ) ? . Value ?? name ;
119
+ var fieldValue = ( TEnum ) field . GetValue ( null ) ;
120
+ dictionary [ fieldValue ] = valueName ;
121
+ }
113
122
114
- throw new ArgumentException ( $ "Unknown value '{ value } ' for enum { typeof ( TEnum ) . Name } ") ;
123
+ return dictionary ;
124
+ }
115
125
}
116
126
}
0 commit comments