@@ -29,9 +29,11 @@ public static class ExpressionExtensions
2929 private static readonly Func < Type , MethodInfo > TupleValueAccessorFactory ;
3030
3131 private static readonly Type MemoryExtensionsType = typeof ( MemoryExtensions ) ;
32- private static readonly MethodInfo ReadOnlySpanContains2 ;
33- private static readonly MethodInfo ReadOnlySpanContains3 ;
34- private static readonly MethodInfo SpanContains ;
32+
33+ private static readonly int [ ] MemoryExtensionsContainsMethodTokens ;
34+ //private static readonly MethodInfo ReadOnlySpanContains2;
35+ //private static readonly MethodInfo ReadOnlySpanContains3;
36+ //private static readonly MethodInfo SpanContains;
3537 private static readonly MethodInfo EnumerableContains ;
3638
3739 ///<summary>
@@ -89,7 +91,7 @@ public static MethodCallExpression TryTransformToOldFashionContains(this MethodC
8991 {
9092 if ( mc . Method . DeclaringType == MemoryExtensionsType ) {
9193 var genericMethod = mc . Method . GetGenericMethodDefinition ( ) ;
92- if ( genericMethod == ReadOnlySpanContains2 || genericMethod == ReadOnlySpanContains3 || genericMethod == SpanContains ) {
94+ if ( MemoryExtensionsContainsMethodTokens . Contains ( genericMethod . MetadataToken ) ) {
9395 var arguments = mc . Arguments ;
9496
9597 Type elementType ;
@@ -98,20 +100,20 @@ public static MethodCallExpression TryTransformToOldFashionContains(this MethodC
98100 if ( arguments [ 0 ] is MethodCallExpression mcInner && mcInner . Method . Name . Equals ( WellKnown . Operator . Implicit , StringComparison . Ordinal ) ) {
99101 var wrappedArray = mcInner . Arguments [ 0 ] ;
100102 elementType = wrappedArray . Type . GetElementType ( ) ;
101- newArguments = new [ ] { wrappedArray , arguments [ 1 ] } ;
103+ newArguments = [ wrappedArray , arguments [ 1 ] ] ;
102104 }
103105 else if ( arguments [ 0 ] is UnaryExpression uInner
104106 && uInner . Method is not null
105107 && uInner . Method . Name . Equals ( WellKnown . Operator . Implicit , StringComparison . Ordinal ) ) {
106108
107109 elementType = uInner . Operand . Type . GetElementType ( ) ;
108- newArguments = new [ ] { uInner . Operand , arguments [ 1 ] } ;
110+ newArguments = [ uInner . Operand , arguments [ 1 ] ] ;
109111 }
110112 else {
111113 return mc ;
112114 }
113115
114- var genericContains = EnumerableContains . MakeGenericMethod ( elementType ) ;
116+ var genericContains = EnumerableContains . CachedMakeGenericMethod ( elementType ) ;
115117 var replacement = Expression . Call ( genericContains , newArguments ) ;
116118 return replacement ;
117119 }
@@ -135,24 +137,20 @@ static ExpressionExtensions()
135137 var filteredByNameItems = MemoryExtensionsType . GetMethods ( BindingFlags . Public | BindingFlags . Static )
136138 . Where ( m => m . Name . Equals ( nameof ( System . MemoryExtensions . Contains ) , StringComparison . OrdinalIgnoreCase ) ) ;
137139
138- var spanCandidates = new List < ( MethodInfo , int ) > ( ) ;
139- var readonlyspanCandidates = new List < ( MethodInfo , int ) > ( ) ;
140+ var candiates = new List < int > ( ) ;
140141
141142 foreach ( var method in filteredByNameItems ) {
142143 var parameters = method . GetParameters ( ) ;
143- var firstParameter = parameters [ 0 ] ;
144- var genericDef = firstParameter . ParameterType . GetGenericTypeDefinition ( ) ;
144+ var genericDef = parameters [ 0 ] . ParameterType . GetGenericTypeDefinition ( ) ;
145145 if ( genericDef == genericReadOnlySpan ) {
146- readonlyspanCandidates . Add ( ( method , parameters . Length ) ) ;
146+ if ( parameters . Length == 2 || parameters . Length == 3 )
147+ candiates . Add ( method . MetadataToken ) ;
147148 }
148- else if ( genericDef == genericSpan ) {
149- spanCandidates . Add ( ( method , parameters . Length ) ) ;
149+ else if ( genericDef == genericSpan && parameters . Length == 2 ) {
150+ candiates . Add ( method . MetadataToken ) ;
150151 }
151152 }
152-
153- ReadOnlySpanContains2 = readonlyspanCandidates . Where ( c => c . Item2 == 2 ) . Select ( c => c . Item1 ) . First ( ) ;
154- ReadOnlySpanContains3 = readonlyspanCandidates . Where ( c => c . Item2 == 3 ) . Select ( c => c . Item1 ) . FirstOrDefault ( ) ;
155- SpanContains = spanCandidates . Where ( c => c . Item2 == 2 ) . Select ( c => c . Item1 ) . First ( ) ;
153+ MemoryExtensionsContainsMethodTokens = candiates . ToArray ( ) ;
156154 EnumerableContains = typeof ( System . Linq . Enumerable ) . GetMethodEx ( nameof ( System . Linq . Enumerable . Contains ) , BindingFlags . Public | BindingFlags . Static , new string [ 1 ] , new object [ 2 ] ) ;
157155 }
158156 }
0 commit comments