@@ -209,7 +209,7 @@ private static void CreateMethods(Type baseType, Type instanceType, FieldInfo in
209209 return x . Version . CompareTo ( y . Version ) ;
210210 } ) ;
211211
212- MethodInfo [ ] allMethods = null ! ;
212+ MethodAttributesSelector [ ] allMethods = null ! ;
213213 foreach ( var duckAttr in duckAttrs )
214214 {
215215 if ( ! ( duckAttr . Version is null ) && asmVersion > duckAttr . Version )
@@ -222,61 +222,68 @@ private static void CreateMethods(Type baseType, Type instanceType, FieldInfo in
222222
223223 if ( ! ( method is null ) )
224224 return method ;
225+
226+ if ( allMethods is null )
227+ {
228+ var methods = instanceType . GetMethods ( duckAttr . Flags ) ;
229+ allMethods = new MethodAttributesSelector [ methods . Length ] ;
230+ for ( var i = 0 ; i < allMethods . Length ; i ++ )
231+ allMethods [ i ] = new MethodAttributesSelector ( methods [ i ] ,
232+ new List < DuckAttribute > ( methods [ i ] . GetCustomAttributes < DuckAttribute > ( true ) ) ) ;
233+ }
225234
226- allMethods ??= instanceType . GetMethods ( duckAttr . Flags ) ;
227-
228- // Trying to select the one with the same name (used by reverse proxy)
229235 var iMethodString = iMethod . ToString ( ) ;
230- var remaining = allMethods . Where ( m =>
236+ var remaining = allMethods . Where ( ma =>
231237 {
232- foreach ( var duckAttribute in m . GetCustomAttributes < DuckAttribute > ( true ) )
238+ if ( ma . Attributes . Count == 0 )
233239 {
234- if ( duckAttribute . Name == iMethodString )
240+ if ( ma . Method . Name != duckAttr . Name ) return false ;
241+
242+ // Trying to select the ones with the same parameters count
243+ var mParams = ma . Method . GetParameters ( ) ;
244+ if ( mParams . Length == parameters . Length )
235245 return true ;
236- }
237- return false ;
238- } ) . ToList ( ) ;
239-
240- if ( remaining . Count == 1 )
241- return remaining [ 0 ] ;
242-
243- // Trying to select the ones with the same parameters count
244- remaining = allMethods . Where ( m =>
245- {
246- if ( m . Name != duckAttr . Name ) return false ;
247-
248- var mParams = m . GetParameters ( ) ;
249- if ( mParams . Length == parameters . Length )
250- return true ;
251246
252- var min = Math . Min ( mParams . Length , parameters . Length ) ;
253- var max = Math . Max ( mParams . Length , parameters . Length ) ;
254- for ( var i = min ; i < max ; i ++ )
247+ var min = Math . Min ( mParams . Length , parameters . Length ) ;
248+ var max = Math . Max ( mParams . Length , parameters . Length ) ;
249+ for ( var i = min ; i < max ; i ++ )
250+ {
251+ if ( mParams . Length > i && ! mParams [ i ] . HasDefaultValue ) return false ;
252+ if ( parameters . Length > i && ! parameters [ i ] . HasDefaultValue ) return false ;
253+ }
254+ return true ;
255+ }
256+ // Trying to select the one with the same name (used by reverse proxy)
257+ foreach ( var attribute in ma . Attributes )
255258 {
256- if ( mParams . Length > i && ! mParams [ i ] . HasDefaultValue ) return false ;
257- if ( parameters . Length > i && ! parameters [ i ] . HasDefaultValue ) return false ;
259+ if ( attribute . Name == iMethodString )
260+ return true ;
258261 }
259- return true ;
262+ return false ;
260263 } ) . ToList ( ) ;
261264
262265 if ( remaining . Count == 0 )
263266 continue ;
264267 if ( remaining . Count == 1 )
265- return remaining [ 0 ] ;
268+ return remaining [ 0 ] . Method ;
269+
270+ var remainWithAttribute = remaining . FirstOrDefault ( r => r . Attributes . Count > 0 ) ;
271+ if ( ! ( remainWithAttribute . Method is null ) )
272+ return remainWithAttribute . Method ;
266273
267274 // Trying to select the ones with the same return type
268- var sameReturnType = remaining . Where ( m => m . ReturnType == iMethod . ReturnType ) . ToList ( ) ;
275+ var sameReturnType = remaining . Where ( ma => ma . Method . ReturnType == iMethod . ReturnType ) . ToList ( ) ;
269276 if ( sameReturnType . Count == 1 )
270- return sameReturnType [ 0 ] ;
277+ return sameReturnType [ 0 ] . Method ;
271278
272279 if ( sameReturnType . Count > 1 )
273280 remaining = sameReturnType ;
274281
275282 if ( iMethod . ReturnType . IsInterface && iMethod . ReturnType . GetInterface ( iMethod . ReturnType . FullName ) == null )
276283 {
277- var duckReturnType = remaining . Where ( m => ! m . ReturnType . IsValueType ) . ToList ( ) ;
284+ var duckReturnType = remaining . Where ( ma => ! ma . Method . ReturnType . IsValueType ) . ToList ( ) ;
278285 if ( duckReturnType . Count == 1 )
279- return duckReturnType [ 0 ] ;
286+ return duckReturnType [ 0 ] . Method ;
280287
281288 if ( duckReturnType . Count > 1 )
282289 remaining = duckReturnType ;
@@ -285,7 +292,7 @@ private static void CreateMethods(Type baseType, Type instanceType, FieldInfo in
285292 // Trying to select the one with the same parameters types
286293 var sameParameters = remaining . Where ( m =>
287294 {
288- var mParams = m . GetParameters ( ) ;
295+ var mParams = m . Method . GetParameters ( ) ;
289296 var min = Math . Min ( mParams . Length , parameters . Length ) ;
290297 for ( var i = 0 ; i < min ; i ++ )
291298 {
@@ -302,12 +309,25 @@ private static void CreateMethods(Type baseType, Type instanceType, FieldInfo in
302309 } ) . ToList ( ) ;
303310
304311 if ( sameParameters . Count == 1 )
305- return sameParameters [ 0 ] ;
312+ return sameParameters [ 0 ] . Method ;
306313
307- return remaining [ 0 ] ;
314+ return remaining [ 0 ] . Method ;
308315 }
309316
310317 return null ;
311318 }
319+
320+ private readonly struct MethodAttributesSelector
321+ {
322+ public readonly MethodInfo Method ;
323+ public readonly List < DuckAttribute > Attributes ;
324+
325+ public MethodAttributesSelector ( MethodInfo methodInfo , List < DuckAttribute > attributes )
326+ {
327+ Method = methodInfo ;
328+ Attributes = attributes ;
329+ }
330+ }
331+
312332 }
313333}
0 commit comments