Skip to content

Commit eb6d1eb

Browse files
committed
Address PR feedback and revert a downlevel change
1 parent ee0a277 commit eb6d1eb

File tree

3 files changed

+58
-52
lines changed

3 files changed

+58
-52
lines changed

src/coreclr/System.Private.CoreLib/src/System/Delegate.CoreCLR.cs

Lines changed: 43 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -156,56 +156,59 @@ public override int GetHashCode()
156156

157157
protected virtual MethodInfo GetMethodImpl()
158158
{
159-
if (_methodBase is null or not MethodInfo)
159+
if (_methodBase is MethodInfo methodInfo)
160160
{
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)
161+
return methodInfo;
162+
}
163+
164+
IRuntimeMethodInfo method = FindMethodHandle();
165+
RuntimeType? declaringType = RuntimeMethodHandle.GetDeclaringType(method);
166+
// need a proper declaring type instance method on a generic type
167+
if (declaringType.IsGenericType)
168+
{
169+
bool isStatic = (RuntimeMethodHandle.GetAttributes(method) & MethodAttributes.Static) != (MethodAttributes)0;
170+
if (!isStatic)
165171
{
166-
bool isStatic = (RuntimeMethodHandle.GetAttributes(method) & MethodAttributes.Static) != (MethodAttributes)0;
167-
if (!isStatic)
172+
if (_methodPtrAux == IntPtr.Zero)
168173
{
169-
if (_methodPtrAux == IntPtr.Zero)
174+
// The target may be of a derived type that doesn't have visibility onto the
175+
// target method. We don't want to call RuntimeType.GetMethodBase below with that
176+
// or reflection can end up generating a MethodInfo where the ReflectedType cannot
177+
// see the MethodInfo itself and that breaks an important invariant. But the
178+
// target type could include important generic type information we need in order
179+
// to work out what the exact instantiation of the method's declaring type is. So
180+
// we'll walk up the inheritance chain (which will yield exactly instantiated
181+
// types at each step) until we find the declaring type. Since the declaring type
182+
// we get from the method is probably shared and those in the hierarchy we're
183+
// walking won't be we compare using the generic type definition forms instead.
184+
Type? currentType = _target!.GetType();
185+
Type targetType = declaringType.GetGenericTypeDefinition();
186+
while (currentType != null)
170187
{
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)
188+
if (currentType.IsGenericType &&
189+
currentType.GetGenericTypeDefinition() == targetType)
184190
{
185-
if (currentType.IsGenericType &&
186-
currentType.GetGenericTypeDefinition() == targetType)
187-
{
188-
declaringType = currentType as RuntimeType;
189-
break;
190-
}
191-
currentType = currentType.BaseType;
191+
declaringType = currentType as RuntimeType;
192+
break;
192193
}
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-
Debug.Assert(currentType != null || _target.GetType().IsCOMObject, "The class hierarchy should declare the method");
198-
}
199-
else
200-
{
201-
// it's an open one, need to fetch the first arg of the instantiation
202-
MethodInfo invoke = this.GetType().GetMethod("Invoke")!;
203-
declaringType = (RuntimeType)invoke.GetParametersAsSpan()[0].ParameterType;
194+
currentType = currentType.BaseType;
204195
}
196+
197+
// RCWs don't need to be "strongly-typed" in which case we don't find a base type
198+
// that matches the declaring type of the method. This is fine because interop needs
199+
// to work with exact methods anyway so declaringType is never shared at this point.
200+
Debug.Assert(currentType != null || _target.GetType().IsCOMObject, "The class hierarchy should declare the method");
201+
}
202+
else
203+
{
204+
// it's an open one, need to fetch the first arg of the instantiation
205+
MethodInfo invoke = this.GetType().GetMethod("Invoke")!;
206+
declaringType = (RuntimeType)invoke.GetParametersAsSpan()[0].ParameterType;
205207
}
206208
}
207-
_methodBase = (MethodInfo)RuntimeType.GetMethodBase(declaringType, method)!;
208209
}
210+
211+
_methodBase = (MethodInfo)RuntimeType.GetMethodBase(declaringType, method)!;
209212
return (MethodInfo)_methodBase;
210213
}
211214

src/coreclr/System.Private.CoreLib/src/System/MulticastDelegate.CoreCLR.cs

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -515,20 +515,23 @@ protected override MethodInfo GetMethodImpl()
515515
{
516516
// we handle unmanaged function pointers here because the generic ones (used for WinRT) would otherwise
517517
// be treated as open delegates by the base implementation, resulting in failure to get the MethodInfo
518-
if (_methodBase is null or not MethodInfo)
518+
if (_methodBase is MethodInfo methodInfo)
519519
{
520-
IRuntimeMethodInfo method = FindMethodHandle();
521-
RuntimeType declaringType = RuntimeMethodHandle.GetDeclaringType(method);
520+
return methodInfo;
521+
}
522522

523-
// need a proper declaring type instance method on a generic type
524-
if (declaringType.IsGenericType)
525-
{
526-
// we are returning the 'Invoke' method of this delegate so use this.GetType() for the exact type
527-
RuntimeType reflectedType = (RuntimeType)GetType();
528-
declaringType = reflectedType;
529-
}
530-
_methodBase = (MethodInfo)RuntimeType.GetMethodBase(declaringType, method)!;
523+
IRuntimeMethodInfo method = FindMethodHandle();
524+
RuntimeType declaringType = RuntimeMethodHandle.GetDeclaringType(method);
525+
526+
// need a proper declaring type instance method on a generic type
527+
if (declaringType.IsGenericType)
528+
{
529+
// we are returning the 'Invoke' method of this delegate so use this.GetType() for the exact type
530+
RuntimeType reflectedType = (RuntimeType)GetType();
531+
declaringType = reflectedType;
531532
}
533+
534+
_methodBase = (MethodInfo)RuntimeType.GetMethodBase(declaringType, method)!;
532535
return (MethodInfo)_methodBase;
533536
}
534537

src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/TypeNameParserHelpers.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ internal static string GetGenericTypeFullName(ReadOnlySpan<char> fullTypeName, R
3434
result.Append(']');
3535
result.Append(',');
3636
}
37-
result[^1] = ']'; // replace ',' with ']'
37+
result[result.Length - 1] = ']'; // replace ',' with ']'
3838

3939
return result.ToString();
4040
}

0 commit comments

Comments
 (0)