I need to know how to find an extension method of a given Type
, given a method name. The usual reflection methods do not work.
For example, the type System.Data.DataTable
, when calling GetMembers
, does not return AsEnumerable
in the results.
To confirm this, I ran:
Dim Query = From MemberInfo As MemberInfo
In GetType(DataTable).GetMembers
Select MemberName = MemberInfo.Name
Order By MemberName
For Each MemberName As String In Query.ToList
Debug.WriteLine(MemberName)
Next
Note that System.Data.DataSetExtensions
is added as a reference, and there is a "using" (Imports) for System.Data
I am looking for the right code to get the MemberInfo
for AsEnumerable
.
Also note that I will not know the Type
at runtime, I'm just using this as a concrete example, so I can't hard-code the solution for DataTable
. I do realize the problem lies elsewhere, is not specific to DataTable
methods, but I think by concrete example of a problem / solution I can extrapolate that to work with every Type
.
EDIT: MY SOLUTION
Calling Code:
Public Function GetMember(Type As Type, MemberName As String) As MemberInfo
Return If(Type.GetMember(MemberName).FirstOrDefault, GetExtensionMethod(Type, MemberName))
End Function
Library Code:
''' <summary>
'''
''' </summary>
''' <param name="ExtendedType">
''' The type that was extended by extension methods
''' </param>
''' <param name="MethodName"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Function GetExtensionMethod(ExtendedType As Type, MethodName As String) As MethodInfo
GetExtensionMethod = GetExtensionMethod(ExtendedType.Assembly, ExtendedType, MethodName)
If GetExtensionMethod IsNot Nothing Then Exit Function
For Each Assembly As Assembly In AppDomain.CurrentDomain.GetAssemblies
GetExtensionMethod = GetExtensionMethod(Assembly, ExtendedType, MethodName)
If GetExtensionMethod IsNot Nothing Then Exit Function
Next
End Function
''' <summary>
'''
''' </summary>
''' <param name="Assembly"></param>
''' <param name="ExtendedType">
''' The type that was extended by extension methods
''' </param>
''' <param name="MethodName"></param>
''' <returns></returns>
Public Function GetExtensionMethod(Assembly As Assembly, ExtendedType As Type, MethodName As String) As MethodInfo
Return GetExtensionMethods(Assembly, ExtendedType).FirstOrDefault(Function(x) x.Name = MethodName)
End Function
''' <summary>
'''
''' </summary>
''' <param name="Assembly"></param>
''' <param name="ExtendedType">
''' The type that was extended by extension methods
''' </param>
''' <returns></returns>
''' <remarks>
''' Reflection's GetMembers does not return extension methods
''' </remarks>
Public Function GetExtensionMethods(Assembly As Assembly, ExtendedType As Type) As IEnumerable(Of MethodInfo)
Dim Query = From Type As Type
In Assembly.GetTypes()
Where Type.IsSealed AndAlso
Not Type.IsGenericType AndAlso
Not Type.IsNested
From Method As MethodInfo
In Type.GetMethods(BindingFlags.[Static] Or BindingFlags.[Public] Or BindingFlags.NonPublic)
Where Method.IsDefined(GetType(ExtensionAttribute), False)
Where Method.GetParameters()(0).ParameterType = ExtendedType
Select Method
Return Query
End Function