@@ -61,7 +61,7 @@ protected Delegate([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.Al
61
61
62
62
if ( target . ContainsGenericParameters )
63
63
throw new ArgumentException ( SR . Arg_UnboundGenParam , nameof ( target ) ) ;
64
- if ( ! ( target is RuntimeType rtTarget ) )
64
+ if ( target is not RuntimeType rtTarget )
65
65
throw new ArgumentException ( SR . Argument_MustBeRuntimeType , nameof ( target ) ) ;
66
66
67
67
// This API existed in v1/v1.1 and only expected to create open
@@ -85,7 +85,6 @@ protected Delegate([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.Al
85
85
return invoke . Invoke ( this , BindingFlags . Default , null , args , null ) ;
86
86
}
87
87
88
-
89
88
public override bool Equals ( [ NotNullWhen ( true ) ] object ? obj )
90
89
{
91
90
if ( obj == null || ! InternalEqualTypes ( this , obj ) )
@@ -107,9 +106,11 @@ public override bool Equals([NotNullWhen(true)] object? obj)
107
106
{
108
107
if ( d . _methodPtrAux != IntPtr . Zero )
109
108
return false ; // different delegate kind
109
+
110
110
// they are both closed over the first arg
111
111
if ( _target != d . _target )
112
112
return false ;
113
+
113
114
// fall through method handle check
114
115
}
115
116
else
@@ -121,19 +122,20 @@ public override bool Equals([NotNullWhen(true)] object? obj)
121
122
/*
122
123
if (_methodPtr != d._methodPtr)
123
124
return false;
124
- */
125
+ */
125
126
126
127
if ( _methodPtrAux == d . _methodPtrAux )
127
128
return true ;
129
+
128
130
// fall through method handle check
129
131
}
130
132
131
133
// 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 )
136
136
return _methodBase . Equals ( d . _methodBase ) ;
137
+ else
138
+ return InternalEqualMethodHandles ( this , d ) ;
137
139
}
138
140
139
141
public override int GetHashCode ( )
@@ -156,60 +158,63 @@ public override int GetHashCode()
156
158
157
159
protected virtual MethodInfo GetMethodImpl ( )
158
160
{
159
- if ( ( _methodBase == null ) || ! ( _methodBase is MethodInfo ) )
161
+ if ( _methodBase is MethodInfo methodInfo )
160
162
{
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 )
165
174
{
166
- bool isStatic = ( RuntimeMethodHandle . GetAttributes ( method ) & MethodAttributes . Static ) != ( MethodAttributes ) 0 ;
167
- if ( ! isStatic )
175
+ if ( _methodPtrAux == IntPtr . Zero )
168
176
{
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 )
170
190
{
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 )
184
193
{
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 ;
192
196
}
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 ;
208
197
}
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 ;
209
213
}
210
214
}
211
- _methodBase = ( MethodInfo ) RuntimeType . GetMethodBase ( declaringType , method ) ! ;
212
215
}
216
+
217
+ _methodBase = ( MethodInfo ) RuntimeType . GetMethodBase ( declaringType , method ) ! ;
213
218
return ( MethodInfo ) _methodBase ;
214
219
}
215
220
@@ -223,7 +228,7 @@ protected virtual MethodInfo GetMethodImpl()
223
228
ArgumentNullException . ThrowIfNull ( target ) ;
224
229
ArgumentNullException . ThrowIfNull ( method ) ;
225
230
226
- if ( ! ( type is RuntimeType rtType ) )
231
+ if ( type is not RuntimeType rtType )
227
232
throw new ArgumentException ( SR . Argument_MustBeRuntimeType , nameof ( type ) ) ;
228
233
if ( ! rtType . IsDelegate ( ) )
229
234
throw new ArgumentException ( SR . Arg_MustBeDelegate , nameof ( type ) ) ;
@@ -260,9 +265,9 @@ protected virtual MethodInfo GetMethodImpl()
260
265
261
266
if ( target . ContainsGenericParameters )
262
267
throw new ArgumentException ( SR . Arg_UnboundGenParam , nameof ( target ) ) ;
263
- if ( ! ( type is RuntimeType rtType ) )
268
+ if ( type is not RuntimeType rtType )
264
269
throw new ArgumentException ( SR . Argument_MustBeRuntimeType , nameof ( type ) ) ;
265
- if ( ! ( target is RuntimeType rtTarget ) )
270
+ if ( target is not RuntimeType rtTarget )
266
271
throw new ArgumentException ( SR . Argument_MustBeRuntimeType , nameof ( target ) ) ;
267
272
268
273
if ( ! rtType . IsDelegate ( ) )
@@ -293,10 +298,10 @@ protected virtual MethodInfo GetMethodImpl()
293
298
ArgumentNullException . ThrowIfNull ( type ) ;
294
299
ArgumentNullException . ThrowIfNull ( method ) ;
295
300
296
- if ( ! ( type is RuntimeType rtType ) )
301
+ if ( type is not RuntimeType rtType )
297
302
throw new ArgumentException ( SR . Argument_MustBeRuntimeType , nameof ( type ) ) ;
298
303
299
- if ( ! ( method is RuntimeMethodInfo rmi ) )
304
+ if ( method is not RuntimeMethodInfo rmi )
300
305
throw new ArgumentException ( SR . Argument_MustBeRuntimeMethodInfo , nameof ( method ) ) ;
301
306
302
307
if ( ! rtType . IsDelegate ( ) )
@@ -328,10 +333,10 @@ protected virtual MethodInfo GetMethodImpl()
328
333
ArgumentNullException . ThrowIfNull ( type ) ;
329
334
ArgumentNullException . ThrowIfNull ( method ) ;
330
335
331
- if ( ! ( type is RuntimeType rtType ) )
336
+ if ( type is not RuntimeType rtType )
332
337
throw new ArgumentException ( SR . Argument_MustBeRuntimeType , nameof ( type ) ) ;
333
338
334
- if ( ! ( method is RuntimeMethodInfo rmi ) )
339
+ if ( method is not RuntimeMethodInfo rmi )
335
340
throw new ArgumentException ( SR . Argument_MustBeRuntimeMethodInfo , nameof ( method ) ) ;
336
341
337
342
if ( ! rtType . IsDelegate ( ) )
@@ -366,7 +371,7 @@ internal static Delegate CreateDelegateNoSecurityCheck(Type type, object? target
366
371
if ( method . IsNullHandle ( ) )
367
372
throw new ArgumentNullException ( nameof ( method ) ) ;
368
373
369
- if ( ! ( type is RuntimeType rtType ) )
374
+ if ( type is not RuntimeType rtType )
370
375
throw new ArgumentException ( SR . Argument_MustBeRuntimeType , nameof ( type ) ) ;
371
376
372
377
if ( ! rtType . IsDelegate ( ) )
0 commit comments