@@ -61,7 +61,7 @@ protected Delegate([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.Al
6161
6262 if ( target . ContainsGenericParameters )
6363 throw new ArgumentException ( SR . Arg_UnboundGenParam , nameof ( target ) ) ;
64- if ( ! ( target is RuntimeType rtTarget ) )
64+ if ( target is not RuntimeType rtTarget )
6565 throw new ArgumentException ( SR . Argument_MustBeRuntimeType , nameof ( target ) ) ;
6666
6767 // This API existed in v1/v1.1 and only expected to create open
@@ -85,7 +85,6 @@ protected Delegate([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.Al
8585 return invoke . Invoke ( this , BindingFlags . Default , null , args , null ) ;
8686 }
8787
88-
8988 public override bool Equals ( [ NotNullWhen ( true ) ] object ? obj )
9089 {
9190 if ( obj == null || ! InternalEqualTypes ( this , obj ) )
@@ -107,9 +106,11 @@ public override bool Equals([NotNullWhen(true)] object? obj)
107106 {
108107 if ( d . _methodPtrAux != IntPtr . Zero )
109108 return false ; // different delegate kind
109+
110110 // they are both closed over the first arg
111111 if ( _target != d . _target )
112112 return false ;
113+
113114 // fall through method handle check
114115 }
115116 else
@@ -121,19 +122,20 @@ public override bool Equals([NotNullWhen(true)] object? obj)
121122 /*
122123 if (_methodPtr != d._methodPtr)
123124 return false;
124- */
125+ */
125126
126127 if ( _methodPtrAux == d . _methodPtrAux )
127128 return true ;
129+
128130 // fall through method handle check
129131 }
130132
131133 // method ptrs don't match, go down long path
132- //
133- if ( _methodBase == null || d . _methodBase == null || ! ( _methodBase is MethodInfo ) || ! ( d . _methodBase is MethodInfo ) )
134- return InternalEqualMethodHandles ( this , d ) ;
135- else
134+
135+ if ( _methodBase is MethodInfo && d . _methodBase is MethodInfo )
136136 return _methodBase . Equals ( d . _methodBase ) ;
137+ else
138+ return InternalEqualMethodHandles ( this , d ) ;
137139 }
138140
139141 public override int GetHashCode ( )
@@ -156,60 +158,63 @@ public override int GetHashCode()
156158
157159 protected virtual MethodInfo GetMethodImpl ( )
158160 {
159- if ( ( _methodBase == null ) || ! ( _methodBase is MethodInfo ) )
161+ if ( _methodBase is MethodInfo methodInfo )
160162 {
161- IRuntimeMethodInfo method = FindMethodHandle ( ) ;
162- RuntimeType ? declaringType = RuntimeMethodHandle . GetDeclaringType ( method ) ;
163- // need a proper declaring type instance method on a generic type
164- if ( declaringType . IsGenericType )
163+ return methodInfo ;
164+ }
165+
166+ IRuntimeMethodInfo method = FindMethodHandle ( ) ;
167+ RuntimeType ? declaringType = RuntimeMethodHandle . GetDeclaringType ( method ) ;
168+
169+ // need a proper declaring type instance method on a generic type
170+ if ( declaringType . IsGenericType )
171+ {
172+ bool isStatic = ( RuntimeMethodHandle . GetAttributes ( method ) & MethodAttributes . Static ) != ( MethodAttributes ) 0 ;
173+ if ( ! isStatic )
165174 {
166- bool isStatic = ( RuntimeMethodHandle . GetAttributes ( method ) & MethodAttributes . Static ) != ( MethodAttributes ) 0 ;
167- if ( ! isStatic )
175+ if ( _methodPtrAux == IntPtr . Zero )
168176 {
169- if ( _methodPtrAux == IntPtr . Zero )
177+ // The target may be of a derived type that doesn't have visibility onto the
178+ // target method. We don't want to call RuntimeType.GetMethodBase below with that
179+ // or reflection can end up generating a MethodInfo where the ReflectedType cannot
180+ // see the MethodInfo itself and that breaks an important invariant. But the
181+ // target type could include important generic type information we need in order
182+ // to work out what the exact instantiation of the method's declaring type is. So
183+ // we'll walk up the inheritance chain (which will yield exactly instantiated
184+ // types at each step) until we find the declaring type. Since the declaring type
185+ // we get from the method is probably shared and those in the hierarchy we're
186+ // walking won't be we compare using the generic type definition forms instead.
187+ Type targetType = declaringType . GetGenericTypeDefinition ( ) ;
188+ Type ? currentType ;
189+ for ( currentType = _target ! . GetType ( ) ; currentType != null ; currentType = currentType . BaseType )
170190 {
171- // The target may be of a derived type that doesn't have visibility onto the
172- // target method. We don't want to call RuntimeType.GetMethodBase below with that
173- // or reflection can end up generating a MethodInfo where the ReflectedType cannot
174- // see the MethodInfo itself and that breaks an important invariant. But the
175- // target type could include important generic type information we need in order
176- // to work out what the exact instantiation of the method's declaring type is. So
177- // we'll walk up the inheritance chain (which will yield exactly instantiated
178- // types at each step) until we find the declaring type. Since the declaring type
179- // we get from the method is probably shared and those in the hierarchy we're
180- // walking won't be we compare using the generic type definition forms instead.
181- Type ? currentType = _target ! . GetType ( ) ;
182- Type targetType = declaringType . GetGenericTypeDefinition ( ) ;
183- while ( currentType != null )
191+ if ( currentType . IsGenericType &&
192+ currentType . GetGenericTypeDefinition ( ) == targetType )
184193 {
185- if ( currentType . IsGenericType &&
186- currentType . GetGenericTypeDefinition ( ) == targetType )
187- {
188- declaringType = currentType as RuntimeType ;
189- break ;
190- }
191- currentType = currentType . BaseType ;
194+ declaringType = currentType as RuntimeType ;
195+ break ;
192196 }
193-
194- // RCWs don't need to be "strongly-typed" in which case we don't find a base type
195- // that matches the declaring type of the method. This is fine because interop needs
196- // to work with exact methods anyway so declaringType is never shared at this point.
197- // The targetType may also be an interface with a Default interface method (DIM).
198- Debug . Assert (
199- currentType != null
200- || _target . GetType ( ) . IsCOMObject
201- || targetType . IsInterface , "The class hierarchy should declare the method or be a DIM" ) ;
202- }
203- else
204- {
205- // it's an open one, need to fetch the first arg of the instantiation
206- MethodInfo invoke = this . GetType ( ) . GetMethod ( "Invoke" ) ! ;
207- declaringType = ( RuntimeType ) invoke . GetParametersAsSpan ( ) [ 0 ] . ParameterType ;
208197 }
198+
199+ // RCWs don't need to be "strongly-typed" in which case we don't find a base type
200+ // that matches the declaring type of the method. This is fine because interop needs
201+ // to work with exact methods anyway so declaringType is never shared at this point.
202+ // The targetType may also be an interface with a Default interface method (DIM).
203+ Debug . Assert (
204+ currentType != null
205+ || _target . GetType ( ) . IsCOMObject
206+ || targetType . IsInterface , "The class hierarchy should declare the method or be a DIM" ) ;
207+ }
208+ else
209+ {
210+ // it's an open one, need to fetch the first arg of the instantiation
211+ MethodInfo invoke = this . GetType ( ) . GetMethod ( "Invoke" ) ! ;
212+ declaringType = ( RuntimeType ) invoke . GetParametersAsSpan ( ) [ 0 ] . ParameterType ;
209213 }
210214 }
211- _methodBase = ( MethodInfo ) RuntimeType . GetMethodBase ( declaringType , method ) ! ;
212215 }
216+
217+ _methodBase = ( MethodInfo ) RuntimeType . GetMethodBase ( declaringType , method ) ! ;
213218 return ( MethodInfo ) _methodBase ;
214219 }
215220
@@ -223,7 +228,7 @@ protected virtual MethodInfo GetMethodImpl()
223228 ArgumentNullException . ThrowIfNull ( target ) ;
224229 ArgumentNullException . ThrowIfNull ( method ) ;
225230
226- if ( ! ( type is RuntimeType rtType ) )
231+ if ( type is not RuntimeType rtType )
227232 throw new ArgumentException ( SR . Argument_MustBeRuntimeType , nameof ( type ) ) ;
228233 if ( ! rtType . IsDelegate ( ) )
229234 throw new ArgumentException ( SR . Arg_MustBeDelegate , nameof ( type ) ) ;
@@ -260,9 +265,9 @@ protected virtual MethodInfo GetMethodImpl()
260265
261266 if ( target . ContainsGenericParameters )
262267 throw new ArgumentException ( SR . Arg_UnboundGenParam , nameof ( target ) ) ;
263- if ( ! ( type is RuntimeType rtType ) )
268+ if ( type is not RuntimeType rtType )
264269 throw new ArgumentException ( SR . Argument_MustBeRuntimeType , nameof ( type ) ) ;
265- if ( ! ( target is RuntimeType rtTarget ) )
270+ if ( target is not RuntimeType rtTarget )
266271 throw new ArgumentException ( SR . Argument_MustBeRuntimeType , nameof ( target ) ) ;
267272
268273 if ( ! rtType . IsDelegate ( ) )
@@ -293,10 +298,10 @@ protected virtual MethodInfo GetMethodImpl()
293298 ArgumentNullException . ThrowIfNull ( type ) ;
294299 ArgumentNullException . ThrowIfNull ( method ) ;
295300
296- if ( ! ( type is RuntimeType rtType ) )
301+ if ( type is not RuntimeType rtType )
297302 throw new ArgumentException ( SR . Argument_MustBeRuntimeType , nameof ( type ) ) ;
298303
299- if ( ! ( method is RuntimeMethodInfo rmi ) )
304+ if ( method is not RuntimeMethodInfo rmi )
300305 throw new ArgumentException ( SR . Argument_MustBeRuntimeMethodInfo , nameof ( method ) ) ;
301306
302307 if ( ! rtType . IsDelegate ( ) )
@@ -328,10 +333,10 @@ protected virtual MethodInfo GetMethodImpl()
328333 ArgumentNullException . ThrowIfNull ( type ) ;
329334 ArgumentNullException . ThrowIfNull ( method ) ;
330335
331- if ( ! ( type is RuntimeType rtType ) )
336+ if ( type is not RuntimeType rtType )
332337 throw new ArgumentException ( SR . Argument_MustBeRuntimeType , nameof ( type ) ) ;
333338
334- if ( ! ( method is RuntimeMethodInfo rmi ) )
339+ if ( method is not RuntimeMethodInfo rmi )
335340 throw new ArgumentException ( SR . Argument_MustBeRuntimeMethodInfo , nameof ( method ) ) ;
336341
337342 if ( ! rtType . IsDelegate ( ) )
@@ -366,7 +371,7 @@ internal static Delegate CreateDelegateNoSecurityCheck(Type type, object? target
366371 if ( method . IsNullHandle ( ) )
367372 throw new ArgumentNullException ( nameof ( method ) ) ;
368373
369- if ( ! ( type is RuntimeType rtType ) )
374+ if ( type is not RuntimeType rtType )
370375 throw new ArgumentException ( SR . Argument_MustBeRuntimeType , nameof ( type ) ) ;
371376
372377 if ( ! rtType . IsDelegate ( ) )
0 commit comments