2014-12-31 86 views
1

我需要知道如何找到一個給定Type的擴展方法,給定一個方法名。通常的反射方法不起作用。如何找到一個擴展方法,給定一個擴展的類型和一個方法名稱

例如,類型System.Data.DataTable在調用GetMembers時,在結果中不返回AsEnumerable

爲了證實這一點,我跑:

  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 

注意System.Data.DataSetExtensions加入作爲參考,並且有一個「使用」(進口)爲System.Data

我正在尋找正確的代碼得到MemberInfoAsEnumerable

另請注意,我不會在運行時知道Type,我只是將其用作一個具體示例,因此我無法對DataTable的解決方案進行硬編碼。我確實意識到問題在於其他地方,並不是特定於DataTable方法,但我認爲通過問題/解決方案的具體示例,我可以推斷該方法與每個Type一起工作。

編輯:我的解決方案

長途區號:

Public Function GetMember(Type As Type, MemberName As String) As MemberInfo 
    Return If(Type.GetMember(MemberName).FirstOrDefault, GetExtensionMethod(Type, MemberName)) 
    End Function 

庫代碼:

''' <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 

回答

2

這是因爲AsEnumerableextension method provided by DataTableExtensions類。你需要調用它,彷彿它是一個簡單的靜態方法:

Dim T As Type 
T = TypeOf DataTableExtensions 
Dim M As Reflection.MethodInfo = T.GetMethod("AsEnumerable") 
... 

我需要能夠發現MemberInfo ...

還有就是要發現所有的擴展沒有一般的方式方法,而不是詳盡地介紹所提供的程序集中的所有類,查找所有可訪問的方法,並檢查它們與第一個參數的特定參數類型以及ExtensionAttribute的兼容性。

This Q & A給出了關於通過反射發現擴展方法的更多信息:link

+0

謝謝,但我需要代碼示例。對不起,我需要一個可以處理所有這些情況的通用解決方案。我需要能夠發現'MemberInfo',因爲下面的代碼調用它。 – toddmo

+0

感謝您的代碼示例,但我怎麼能發現'DataTableExtensions'與'DataTable'有關? – toddmo

+0

正確的擴展方法將作爲第一個參數具有我感興趣的'Type'(在本例中爲'DataTable')作爲第一個參數,對嗎? – toddmo

相關問題