@@ -2139,7 +2139,7 @@ private bool TryParseEnumerable(Expression instance, Type enumerableType, string
21392139 // Create a new innerIt based on the elementType.
21402140 var innerIt = ParameterExpressionHelper . CreateParameterExpression ( elementType , string . Empty , _parsingConfig . RenameEmptyParameterExpressionNames ) ;
21412141
2142- if ( new [ ] { "Contains" , "ContainsKey" , "Skip" , "Take" } . Contains ( methodName ) )
2142+ if ( CanonicalContains ( [ "Contains" , "ContainsKey" , "Skip" , "Take" ] , ref methodName ) )
21432143 {
21442144 // For any method that acts on the parent element type, we need to specify the outerIt as scope.
21452145 _it = outerIt ;
@@ -2194,7 +2194,7 @@ private bool TryParseEnumerable(Expression instance, Type enumerableType, string
21942194 }
21952195
21962196 Type [ ] typeArgs ;
2197- if ( new [ ] { "OfType" , "Cast" } . Contains ( methodName ) )
2197+ if ( CanonicalContains ( [ "OfType" , "Cast" ] , ref methodName ) )
21982198 {
21992199 if ( args . Length != 1 )
22002200 {
@@ -2204,7 +2204,7 @@ private bool TryParseEnumerable(Expression instance, Type enumerableType, string
22042204 typeArgs = [ ResolveTypeFromArgumentExpression ( methodName , args [ 0 ] ) ] ;
22052205 args = [ ] ;
22062206 }
2207- else if ( new [ ] { "Max" , "Min" , "Select" , "OrderBy" , "OrderByDescending" , "ThenBy" , "ThenByDescending" , "GroupBy" } . Contains ( methodName ) )
2207+ else if ( CanonicalContains ( [ "Max" , "Min" , "Select" , "OrderBy" , "OrderByDescending" , "ThenBy" , "ThenByDescending" , "GroupBy" ] , ref methodName ) )
22082208 {
22092209 if ( args . Length == 2 )
22102210 {
@@ -2219,7 +2219,7 @@ private bool TryParseEnumerable(Expression instance, Type enumerableType, string
22192219 typeArgs = [ elementType ] ;
22202220 }
22212221 }
2222- else if ( methodName == "SelectMany" )
2222+ else if ( CanonicalContains ( [ "SelectMany" ] , ref methodName ) )
22232223 {
22242224 var bodyType = Expression . Lambda ( args [ 0 ] , innerIt ) . Body . Type ;
22252225 var interfaces = bodyType . GetInterfaces ( ) . Union ( [ bodyType ] ) ;
@@ -2238,7 +2238,7 @@ private bool TryParseEnumerable(Expression instance, Type enumerableType, string
22382238 }
22392239 else
22402240 {
2241- if ( new [ ] { "Concat" , "Contains" , "ContainsKey" , "DefaultIfEmpty" , "Except" , "Intersect" , "Skip" , "Take" , "Union" , "SequenceEqual" } . Contains ( methodName ) )
2241+ if ( CanonicalContains ( [ "Concat" , "Contains" , "ContainsKey" , "DefaultIfEmpty" , "Except" , "Intersect" , "Skip" , "Take" , "Union" , "SequenceEqual" ] , ref methodName ) )
22422242 {
22432243 args = [ instance , args [ 0 ] ] ;
22442244 }
@@ -2259,6 +2259,25 @@ private bool TryParseEnumerable(Expression instance, Type enumerableType, string
22592259 return true ;
22602260 }
22612261
2262+ private bool CanonicalContains ( string [ ] haystack , ref string needle )
2263+ {
2264+ if ( _parsingConfig . IsCaseSensitive )
2265+ {
2266+ return haystack . Contains ( needle ) ;
2267+ }
2268+
2269+ var element = needle ;
2270+ var index = Array . FindIndex ( haystack , item => item . Equals ( element , StringComparison . OrdinalIgnoreCase ) ) ;
2271+
2272+ if ( index == - 1 )
2273+ {
2274+ return false ;
2275+ }
2276+
2277+ needle = haystack [ index ] ;
2278+ return true ;
2279+ }
2280+
22622281 private Type ResolveTypeFromArgumentExpression ( string functionName , Expression argumentExpression , int ? arguments = null )
22632282 {
22642283 var argument = arguments == null ? string . Empty : arguments == 1 ? "first " : "second " ;
0 commit comments