public static RuntimeMethodInfo GetInvokeMethod(this RuntimeTypeInfo delegateType) { Debug.Assert(delegateType.IsDelegate); MethodInfo?invokeMethod = delegateType.GetMethod("Invoke", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly); if (invokeMethod == null) { // No Invoke method found. Since delegate types are compiler constructed, the most likely cause is missing metadata rather than // a missing Invoke method. throw ReflectionCoreExecution.ExecutionDomain.CreateMissingMetadataException(delegateType); } return((RuntimeMethodInfo)invokeMethod); }
public static RuntimeMethodInfo GetInvokeMethod(this RuntimeTypeInfo delegateType) { Debug.Assert(delegateType.IsDelegate); MethodInfo invokeMethod = delegateType.GetMethod("Invoke", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly); if (invokeMethod == null) { // No Invoke method found. Since delegate types are compiler constructed, the most likely cause is missing metadata rather than // a missing Invoke method. // We're deliberating calling FullName rather than ToString() because if it's the type that's missing metadata, // the FullName property constructs a more informative MissingMetadataException than we can. string fullName = delegateType.FullName; throw new MissingMetadataException(SR.Format(SR.Arg_InvokeMethodMissingMetadata, fullName)); // No invoke method found. } return((RuntimeMethodInfo)invokeMethod); }
// // Helper for the V1/V1.1 Delegate.CreateDelegate() api. These apis take method names rather than MethodInfo and only expect to create open static delegates // or closed instance delegates. For backward compatibility, they don't allow relaxed signature matching (which could make the choice of target method ambiguous.) // private static RuntimeMethodInfo LookupMethodForCreateDelegate(RuntimeTypeInfo runtimeDelegateType, RuntimeTypeInfo containingType, string method, bool isStatic, bool ignoreCase) { Debug.Assert(runtimeDelegateType.IsDelegate); BindingFlags bindingFlags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.ExactBinding; if (isStatic) { bindingFlags |= BindingFlags.Static | BindingFlags.FlattenHierarchy; } else { bindingFlags |= BindingFlags.Instance; } if (ignoreCase) { bindingFlags |= BindingFlags.IgnoreCase; } RuntimeMethodInfo invokeMethod = runtimeDelegateType.GetInvokeMethod(); ParameterInfo[] parameters = invokeMethod.GetParametersNoCopy(); int numParameters = parameters.Length; Type[] parameterTypes = new Type[numParameters]; for (int i = 0; i < numParameters; i++) { parameterTypes[i] = parameters[i].ParameterType; } MethodInfo methodInfo = containingType.GetMethod(method, bindingFlags, null, parameterTypes, null); if (methodInfo == null) { return(null); } if (!methodInfo.ReturnType.Equals(invokeMethod.ReturnType)) { return(null); } return((RuntimeMethodInfo)methodInfo); // This cast is safe since we already verified that containingType is runtime implemented. }
// // Helper for the V1/V1.1 Delegate.CreateDelegate() api. These apis take method names rather than MethodInfo and only expect to create open static delegates // or closed instance delegates. For backward compatibility, they don't allow relaxed signature matching (which could make the choice of target method ambiguous.) // private static RuntimeMethodInfo LookupMethodForCreateDelegate(RuntimeTypeInfo runtimeDelegateType, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] RuntimeTypeInfo containingType, string method, bool isStatic, bool ignoreCase) { Debug.Assert(runtimeDelegateType.IsDelegate); BindingFlags bindingFlags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.ExactBinding; if (isStatic) { bindingFlags |= BindingFlags.Static; } else { bindingFlags |= BindingFlags.Instance | BindingFlags.DeclaredOnly; } if (ignoreCase) { bindingFlags |= BindingFlags.IgnoreCase; } RuntimeMethodInfo invokeMethod = runtimeDelegateType.GetInvokeMethod(); ParameterInfo[] parameters = invokeMethod.GetParametersNoCopy(); int numParameters = parameters.Length; Type[] parameterTypes = new Type[numParameters]; for (int i = 0; i < numParameters; i++) { parameterTypes[i] = parameters[i].ParameterType; } while (containingType != null) { MethodInfo?methodInfo = containingType.GetMethod(method, 0, bindingFlags, null, parameterTypes, null); if (methodInfo != null && methodInfo.ReturnType.Equals(invokeMethod.ReturnType)) { return((RuntimeMethodInfo)methodInfo); // This cast is safe since we already verified that containingType is runtime implemented. } #pragma warning disable IL2072 // https://github.com/dotnet/linker/issues/2673 containingType = (RuntimeTypeInfo)(containingType.BaseType); #pragma warning restore } return(null); }