11using System ;
2- using System . Collections . Generic ;
32using System . Collections . Immutable ;
43using System . Diagnostics ;
54using System . Linq ;
6- using System . Linq . Expressions ;
7- using System . Runtime . CompilerServices ;
85
96namespace Open . Text
107{
@@ -43,72 +40,35 @@ public EnumValue(string value)
4340 /// </summary>
4441 public override string ToString ( ) => Value . ToString ( ) ;
4542
46- static readonly Func < string , TEnum > Parser = CreateParseEnumDelegate ( ) ;
43+ internal static readonly ImmutableDictionary < string , TEnum > Lookup = CreateLookup ( ) ;
4744
4845 /// <summary>
49- /// Uses an expression tree switch to get a matching enum value.
46+ /// Uses a case-senstive dictionary lookup to get a matching enum value.
5047 /// </summary>
5148 /// <param name="value">The string represnting the enum to search for.</param>
5249 /// <returns>The enum that represents the string <paramref name="value"/> provided.</returns>
5350 /// <exception cref="ArgumentNullException">value is null</exception>
5451 /// <exception cref="ArgumentException">Requested <paramref name="value"/> was not found.</exception>
5552 public static TEnum Parse ( string value )
56- {
57- if ( value is null )
58- throw new ArgumentNullException ( nameof ( value ) ) ;
59-
60- try
61- {
62- return Parser ( value ) ;
63- }
64- catch ( ArgumentException ex )
65- {
66- throw new ArgumentException ( $ "Requested value '{ value } ' was not found.", nameof ( value ) , ex ) ;
67- }
68- }
53+ => TryParse ( value , out var e ) ? e : throw new ArgumentException ( $ "Requested value '{ value } ' was not found.", nameof ( value ) ) ;
6954
7055 /// <summary>
71- /// Uses an expression tree switch to get a matching enum value.
56+ /// Uses a case-senstive dictionary lookup to get a matching enum value.
7257 /// </summary>
7358 /// <returns>true if the value found; otherwise false.</returns>
7459 /// <exception cref="ArgumentNullException"/>
7560 public static bool TryParse ( string value , out TEnum e )
7661 {
77- try
78- {
79- e = Parser ( value ) ;
80- return true ;
81- }
82- catch ( ArgumentException )
83- {
84- e = default ! ;
85- return false ;
86- }
62+ if ( Lookup . TryGetValue ( value , out e ! ) ) return true ;
63+ e = default ! ;
64+ return false ;
8765 }
8866
89- // https://stackoverflow.com/questions/26678181/enum-parse-vs-switch-performance
90- static Func < string , TEnum > CreateParseEnumDelegate ( )
91- {
92- var eValue = Expression . Parameter ( typeof ( string ) , "value" ) ; // (string value)
93- var tEnum = typeof ( TEnum ) ;
94-
95- return
96- Expression . Lambda < Func < string , TEnum > > (
97- Expression . Block ( tEnum ,
98- Expression . Switch ( tEnum , eValue ,
99- Expression . Block ( tEnum ,
100- Expression . Throw ( Expression . New ( typeof ( ArgumentException ) . GetConstructor ( Type . EmptyTypes ) ) ) ,
101- Expression . Default ( tEnum )
102- ) ,
103- null ,
104- Enum . GetValues ( tEnum ) . Cast < object > ( ) . Select ( v => Expression . SwitchCase (
105- Expression . Constant ( v ) ,
106- Expression . Constant ( v . ToString ( ) )
107- ) ) . ToArray ( )
108- )
109- ) , eValue
110- ) . Compile ( ) ;
111- }
67+ static ImmutableDictionary < string , TEnum > CreateLookup ( )
68+ => Enum
69+ . GetValues ( typeof ( TEnum ) )
70+ . Cast < TEnum > ( )
71+ . ToImmutableDictionary ( v => v . ToString ( ) , v => v ) ;
11272
11373 /// <summary>
11474 /// Indicates whether this instance matches the enum value of <paramref name="other"/>.
@@ -184,14 +144,12 @@ public EnumValueCaseIgnored(string value)
184144 /// <inheritdoc cref="EnumValue{TEnum}.ToString"/>
185145 public override string ToString ( ) => Value . ToString ( ) ;
186146
187- internal static readonly ImmutableDictionary < string , TEnum > CaseInsensitiveLookup
188- = CreateCaseInsensitiveDictionary ( ) ;
147+ internal static readonly ImmutableDictionary < string , TEnum > Lookup = CreateLookup ( ) ;
189148
190149 /// <summary>
191150 /// Uses a case-insenstive dictionary lookup to get a matching enum value.
192151 /// </summary>
193152 /// <inheritdoc cref="EnumValue{TEnum}.Parse(string)" />
194- [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
195153 public static TEnum Parse ( string value )
196154 => TryParse ( value , out var e ) ? e : throw new ArgumentException ( $ "Requested value '{ value } ' was not found.", nameof ( value ) ) ;
197155
@@ -201,12 +159,12 @@ public static TEnum Parse(string value)
201159 /// <inheritdoc cref="EnumValue{TEnum}.TryParse(string, out TEnum)"/>
202160 public static bool TryParse ( string value , out TEnum e )
203161 {
204- if ( CaseInsensitiveLookup . TryGetValue ( value , out e ! ) ) return true ;
162+ if ( Lookup . TryGetValue ( value , out e ! ) ) return true ;
205163 e = default ! ;
206164 return false ;
207165 }
208166
209- static ImmutableDictionary < string , TEnum > CreateCaseInsensitiveDictionary ( )
167+ static ImmutableDictionary < string , TEnum > CreateLookup ( )
210168 => Enum
211169 . GetValues ( typeof ( TEnum ) )
212170 . Cast < TEnum > ( )
0 commit comments