Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Type.GetMethod overload that takes Name, BindingFlags, and Parameter Types #44529

Merged
merged 2 commits into from
Nov 11, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions src/libraries/System.Private.CoreLib/src/System/Type.cs
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,27 @@ public ConstructorInfo? TypeInitializer
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)]
public ConstructorInfo? GetConstructor(Type[] types) => GetConstructor(BindingFlags.Public | BindingFlags.Instance, null, types, null);

/// <summary>
/// Searches for a constructor whose parameters match the specified argument types, using the specified binding constraints.
/// </summary>
/// <param name="bindingAttr">
/// A bitwise combination of the enumeration values that specify how the search is conducted.
/// -or-
/// Default to return null.
/// </param>
/// <param name="types">
/// An array of Type objects representing the number, order, and type of the parameters for the constructor to get.
/// -or-
/// An empty array of the type <see cref="Type"/> (that is, Type[] types = Array.Empty{Type}()) to get a constructor that takes no parameters.
/// -or-
/// <see cref="EmptyTypes"/>.
/// </param>
/// <returns>
/// A <see cref="ConstructorInfo"/> object representing the constructor that matches the specified requirements, if found; otherwise, null.
/// </returns>
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)]
public ConstructorInfo? GetConstructor(BindingFlags bindingAttr, Type[] types) => GetConstructor(bindingAttr, binder: null, types, modifiers: null);

[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)]
public ConstructorInfo? GetConstructor(BindingFlags bindingAttr, Binder? binder, Type[] types, ParameterModifier[]? modifiers) => GetConstructor(bindingAttr, binder, CallingConventions.Any, types, modifiers);

Expand Down Expand Up @@ -221,6 +242,24 @@ public ConstructorInfo? TypeInitializer
return GetMethodImpl(name, bindingAttr, null, CallingConventions.Any, null, null);
}

/// <summary>
/// Searches for the specified method whose parameters match the specified argument types, using the specified binding constraints.
/// </summary>
/// <param name="name">The string containing the name of the method to get.</param>
/// <param name="bindingAttr">
/// A bitwise combination of the enumeration values that specify how the search is conducted.
/// -or-
/// Default to return null.
/// </param>
/// <param name="types">
/// An array of <see cref="Type"/> objects representing the number, order, and type of the parameters for the method to get.
/// -or-
/// An empty array of <see cref="Type"/> objects (as provided by the <see cref="EmptyTypes"/> field) to get a method that takes no parameters.
/// </param>
/// <returns>An object representing the method that matches the specified requirements, if found; otherwise, null.</returns>
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)]
public MethodInfo? GetMethod(string name, BindingFlags bindingAttr, Type[] types) => GetMethod(name, bindingAttr, binder: null, types, modifiers: null);

[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)]
public MethodInfo? GetMethod(string name, Type[] types) => GetMethod(name, types, null);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -388,7 +388,7 @@ internal static bool IsNonAttributedTypeValidForSerialization(Type type)
else
{
return (type.IsVisible &&
type.GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public, null, Array.Empty<Type>(), null) != null);
type.GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public, Array.Empty<Type>()) != null);
}
}

Expand Down Expand Up @@ -1368,7 +1368,7 @@ private void SetKeyValuePairAdapterFlags(Type type)
{
_isKeyValuePairAdapter = true;
_keyValuePairGenericArguments = type.GetGenericArguments();
_keyValuePairCtorInfo = type.GetConstructor(Globals.ScanAllMembers, null, new Type[] { Globals.TypeOfKeyValuePair.MakeGenericType(_keyValuePairGenericArguments) }, null);
_keyValuePairCtorInfo = type.GetConstructor(Globals.ScanAllMembers, new Type[] { Globals.TypeOfKeyValuePair.MakeGenericType(_keyValuePairGenericArguments) });
_getKeyValuePairMethodInfo = type.GetMethod("GetKeyValuePair", Globals.ScanAllMembers)!;
}
}
Expand Down Expand Up @@ -1408,7 +1408,7 @@ internal MethodInfo? GetKeyValuePairMethodInfo
if (!IsISerializable)
return null;

ConstructorInfo? ctor = UnderlyingType.GetConstructor(Globals.ScanAllMembers, null, SerInfoCtorArgs, null);
ConstructorInfo? ctor = UnderlyingType.GetConstructor(Globals.ScanAllMembers, SerInfoCtorArgs);
if (ctor == null)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.Format(SR.SerializationInfo_ConstructorNotFound, DataContract.GetClrTypeFullName(UnderlyingType))));

Expand All @@ -1425,7 +1425,7 @@ internal MethodInfo? GetKeyValuePairMethodInfo
if (type.IsValueType)
return null;

ConstructorInfo? ctor = type.GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public, null, Array.Empty<Type>(), null);
ConstructorInfo? ctor = type.GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public, Array.Empty<Type>());
if (ctor == null)
throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.Format(SR.NonAttributedSerializableTypesMustHaveDefaultConstructor, DataContract.GetClrTypeFullName(type))));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -883,7 +883,7 @@ internal Type GetCollectionElementType()
enumeratorType = GetEnumeratorMethod.ReturnType;
}

MethodInfo? getCurrentMethod = enumeratorType.GetMethod(Globals.GetCurrentMethodName, BindingFlags.Instance | BindingFlags.Public, null, Array.Empty<Type>(), null);
MethodInfo? getCurrentMethod = enumeratorType.GetMethod(Globals.GetCurrentMethodName, BindingFlags.Instance | BindingFlags.Public, Array.Empty<Type>());
if (getCurrentMethod == null)
{
if (enumeratorType.IsInterface)
Expand Down Expand Up @@ -1145,7 +1145,7 @@ private static bool IsCollectionOrTryCreate(Type type, bool tryCreate, out DataC
ConstructorInfo? defaultCtor = null;
if (!type.IsValueType)
{
defaultCtor = type.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Array.Empty<Type>(), null);
defaultCtor = type.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, Array.Empty<Type>());
if (defaultCtor == null && constructorRequired)
{
// All collection types could be considered read-only collections except collection types that are marked [Serializable].
Expand Down Expand Up @@ -1331,7 +1331,7 @@ private static void GetCollectionMethods(Type type, Type interfaceType, Type[] a

if (addMethodOnInterface)
{
addMethod = type.GetMethod(Globals.AddMethodName, BindingFlags.Instance | BindingFlags.Public, null, addMethodTypeArray, null);
addMethod = type.GetMethod(Globals.AddMethodName, BindingFlags.Instance | BindingFlags.Public, addMethodTypeArray);
if (addMethod == null || addMethod.GetParameters()[0].ParameterType != addMethodTypeArray[0])
{
FindCollectionMethodsOnInterface(type, interfaceType, ref addMethod, ref getEnumeratorMethod);
Expand Down Expand Up @@ -1359,12 +1359,12 @@ private static void GetCollectionMethods(Type type, Type interfaceType, Type[] a
else
{
// GetMethod returns Add() method with parameter closest matching T in assignability/inheritance chain
addMethod = type.GetMethod(Globals.AddMethodName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, addMethodTypeArray, null);
addMethod = type.GetMethod(Globals.AddMethodName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, addMethodTypeArray);
}

if (getEnumeratorMethod == null)
{
getEnumeratorMethod = type.GetMethod(Globals.GetEnumeratorMethodName, BindingFlags.Instance | BindingFlags.Public, null, Array.Empty<Type>(), null);
getEnumeratorMethod = type.GetMethod(Globals.GetEnumeratorMethodName, BindingFlags.Instance | BindingFlags.Public, Array.Empty<Type>());
if (getEnumeratorMethod == null || !Globals.TypeOfIEnumerator.IsAssignableFrom(getEnumeratorMethod.ReturnType))
{
Type? ienumerableInterface = interfaceType.GetInterfaces().Where(t => t.FullName!.StartsWith("System.Collections.Generic.IEnumerable")).FirstOrDefault();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1126,7 +1126,7 @@ internal MethodInfo? ParseMethod
{
if (!_parseMethodSet)
{
MethodInfo? method = UnderlyingType.GetMethod(Globals.ParseMethodName, BindingFlags.Public | BindingFlags.Static, null, new Type[] { typeof(string) }, null);
MethodInfo? method = UnderlyingType.GetMethod(Globals.ParseMethodName, BindingFlags.Public | BindingFlags.Static, new Type[] { typeof(string) });

if (method != null && method.ReturnType == UnderlyingType)
{
Expand Down Expand Up @@ -1979,7 +1979,7 @@ private static void ImportKnownTypeAttributes(Type? type, Dictionary<Type, Type>
if (methodName.Length == 0)
DataContract.ThrowInvalidDataContractException(SR.Format(SR.KnownTypeAttributeEmptyString, DataContract.GetClrTypeFullName(type)), type);

MethodInfo? method = type.GetMethod(methodName, BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public, null, Array.Empty<Type>(), null);
MethodInfo? method = type.GetMethod(methodName, BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public, Array.Empty<Type>());
if (method == null)
DataContract.ThrowInvalidDataContractException(SR.Format(SR.KnownTypeAttributeUnknownMethod, methodName, DataContract.GetClrTypeFullName(type)), type);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ public static PropertyInfo CollectionItemNameProperty

public static ConstructorInfo ExtensionDataObjectCtor => s_extensionDataObjectCtor ??
(s_extensionDataObjectCtor =
typeof(ExtensionDataObject).GetConstructor(Globals.ScanAllMembers, null, Array.Empty<Type>(), null))!;
typeof(ExtensionDataObject).GetConstructor(Globals.ScanAllMembers, Array.Empty<Type>()))!;

public static PropertyInfo ExtensionDataProperty => s_extensionDataProperty ??
(s_extensionDataProperty = typeof(IExtensibleDataObject).GetProperty("ExtensionData")!);
Expand Down Expand Up @@ -167,7 +167,7 @@ public static MethodInfo GetUninitializedObjectMethod
{
if (s_getUninitializedObjectMethod == null)
{
s_getUninitializedObjectMethod = typeof(XmlFormatReaderGenerator).GetMethod("UnsafeGetUninitializedObject", Globals.ScanAllMembers, null, new Type[] { typeof(Type) }, null);
s_getUninitializedObjectMethod = typeof(XmlFormatReaderGenerator).GetMethod("UnsafeGetUninitializedObject", Globals.ScanAllMembers, new Type[] { typeof(Type) });
Debug.Assert(s_getUninitializedObjectMethod != null);
}
return s_getUninitializedObjectMethod;
Expand All @@ -180,7 +180,7 @@ public static MethodInfo IsStartElementMethod0
{
if (s_isStartElementMethod0 == null)
{
s_isStartElementMethod0 = typeof(XmlReaderDelegator).GetMethod("IsStartElement", Globals.ScanAllMembers, null, Array.Empty<Type>(), null);
s_isStartElementMethod0 = typeof(XmlReaderDelegator).GetMethod("IsStartElement", Globals.ScanAllMembers, Array.Empty<Type>());
Debug.Assert(s_isStartElementMethod0 != null);
}
return s_isStartElementMethod0;
Expand All @@ -192,7 +192,7 @@ public static MethodInfo IsStartElementMethod2
{
if (s_isStartElementMethod2 == null)
{
s_isStartElementMethod2 = typeof(XmlReaderDelegator).GetMethod("IsStartElement", Globals.ScanAllMembers, null, new Type[] { typeof(XmlDictionaryString), typeof(XmlDictionaryString) }, null);
s_isStartElementMethod2 = typeof(XmlReaderDelegator).GetMethod("IsStartElement", Globals.ScanAllMembers, new Type[] { typeof(XmlDictionaryString), typeof(XmlDictionaryString) });
Debug.Assert(s_isStartElementMethod2 != null);
}
return s_isStartElementMethod2;
Expand Down Expand Up @@ -371,7 +371,7 @@ public static MethodInfo WriteAttributeStringMethod
{
if (s_writeAttributeStringMethod == null)
{
s_writeAttributeStringMethod = typeof(XmlWriterDelegator).GetMethod("WriteAttributeString", Globals.ScanAllMembers, null, new Type[] { typeof(string), typeof(string), typeof(string), typeof(string) }, null);
s_writeAttributeStringMethod = typeof(XmlWriterDelegator).GetMethod("WriteAttributeString", Globals.ScanAllMembers, new Type[] { typeof(string), typeof(string), typeof(string), typeof(string) });
Debug.Assert(s_writeAttributeStringMethod != null);
}
return s_writeAttributeStringMethod;
Expand All @@ -383,7 +383,7 @@ public static MethodInfo WriteEndElementMethod
{
if (s_writeEndElementMethod == null)
{
s_writeEndElementMethod = typeof(XmlWriterDelegator).GetMethod("WriteEndElement", Globals.ScanAllMembers, null, Array.Empty<Type>(), null);
s_writeEndElementMethod = typeof(XmlWriterDelegator).GetMethod("WriteEndElement", Globals.ScanAllMembers, Array.Empty<Type>());
Debug.Assert(s_writeEndElementMethod != null);
}
return s_writeEndElementMethod;
Expand Down Expand Up @@ -431,7 +431,7 @@ public static MethodInfo WriteStartElementMethod
{
if (s_writeStartElementMethod == null)
{
s_writeStartElementMethod = typeof(XmlWriterDelegator).GetMethod("WriteStartElement", Globals.ScanAllMembers, null, new Type[] { typeof(XmlDictionaryString), typeof(XmlDictionaryString) }, null);
s_writeStartElementMethod = typeof(XmlWriterDelegator).GetMethod("WriteStartElement", Globals.ScanAllMembers, new Type[] { typeof(XmlDictionaryString), typeof(XmlDictionaryString) });
Debug.Assert(s_writeStartElementMethod != null);
}
return s_writeStartElementMethod;
Expand All @@ -444,7 +444,7 @@ public static MethodInfo WriteStartElementStringMethod
{
if (s_writeStartElementStringMethod == null)
{
s_writeStartElementStringMethod = typeof(XmlWriterDelegator).GetMethod("WriteStartElement", Globals.ScanAllMembers, null, new Type[] { typeof(string), typeof(string) }, null);
s_writeStartElementStringMethod = typeof(XmlWriterDelegator).GetMethod("WriteStartElement", Globals.ScanAllMembers, new Type[] { typeof(string), typeof(string) });
Debug.Assert(s_writeStartElementStringMethod != null);
}
return s_writeStartElementStringMethod;
Expand All @@ -457,7 +457,7 @@ public static MethodInfo ParseEnumMethod
{
if (s_parseEnumMethod == null)
{
s_parseEnumMethod = typeof(Enum).GetMethod("Parse", BindingFlags.Static | BindingFlags.Public, null, new Type[] { typeof(Type), typeof(string) }, null);
s_parseEnumMethod = typeof(Enum).GetMethod("Parse", BindingFlags.Static | BindingFlags.Public, new Type[] { typeof(Type), typeof(string) });
Debug.Assert(s_parseEnumMethod != null);
}
return s_parseEnumMethod;
Expand All @@ -470,7 +470,7 @@ public static MethodInfo GetJsonMemberNameMethod
{
if (s_getJsonMemberNameMethod == null)
{
s_getJsonMemberNameMethod = typeof(XmlObjectSerializerReadContextComplexJson).GetMethod("GetJsonMemberName", Globals.ScanAllMembers, null, new Type[] { typeof(XmlReaderDelegator) }, null);
s_getJsonMemberNameMethod = typeof(XmlObjectSerializerReadContextComplexJson).GetMethod("GetJsonMemberName", Globals.ScanAllMembers, new Type[] { typeof(XmlReaderDelegator) });
Debug.Assert(s_getJsonMemberNameMethod != null);
}
return s_getJsonMemberNameMethod;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -430,7 +430,7 @@ private void ResetExpectedElements(BitFlagsGenerator expectedElements, int index

private void ReadISerializable(ClassDataContract classContract)
{
ConstructorInfo? ctor = classContract.UnderlyingType.GetConstructor(Globals.ScanAllMembers, null, JsonFormatGeneratorStatics.SerInfoCtorArgs, null);
ConstructorInfo? ctor = classContract.UnderlyingType.GetConstructor(Globals.ScanAllMembers, JsonFormatGeneratorStatics.SerInfoCtorArgs);
if (ctor == null)
throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.Format(SR.SerializationInfo_ConstructorNotFound, DataContract.GetClrTypeFullName(classContract.UnderlyingType))));
_ilg.LoadAddress(_objectLocal);
Expand Down Expand Up @@ -573,11 +573,11 @@ private void ReadCollection(CollectionDataContract collectionContract)
{
case CollectionKind.GenericDictionary:
type = Globals.TypeOfDictionaryGeneric.MakeGenericType(itemType.GetGenericArguments());
constructor = type.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Array.Empty<Type>(), null)!;
constructor = type.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, Array.Empty<Type>())!;
break;
case CollectionKind.Dictionary:
type = Globals.TypeOfHashtable;
constructor = type.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Array.Empty<Type>(), null)!;
constructor = type.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, Array.Empty<Type>())!;
break;
case CollectionKind.Collection:
case CollectionKind.GenericCollection:
Expand Down
Loading