Не удается получить список объявленных методов в классе .net - PullRequest
0 голосов
/ 16 апреля 2019

Прочитав очень много постов об использовании рефлексии, чтобы получить список методов в данном классе, я все еще испытываю трудности с получением этого списка, и мне нужно обратиться за помощью. Это мой текущий код:

Function GetClassMethods(ByVal theType As Type) As List(Of String)
    Dim methodNames As New List(Of String)
    For Each method In theType.GetMethods()
        methodNames.Add(method.Name)
    Next
    Return methodNames
End Function

Я называю этот метод так:

GetClassMethods(GetType(HomeController))

В возвращении есть 43 метода, но мне нужны только методы, которые я написал в классе. Изображение ниже показывает начало того, что было возвращено. Мои объявленные методы находятся в этом списке, но находятся в месте 31-37. На самом деле существует 9 объявленных методов, но этот список не показывает методы Private.

enter image description here

Когда я смотрю на theType, я вижу желаемое свойство. Это DeclaredMethods, который показывает каждый объявленный метод, публичный и приватный.

enter image description here

Однако я не могу получить доступ к этому свойству с помощью такого заявления.

Dim methodList = theType.DeclaredMethods

Возвращенная ошибка: DelaredMethods не является членом Type. Итак, у меня несколько вопросов:

1) Самое главное, какой код мне нужен для получения каждого объявленного метода в классе, и только методов, которые я объявил?

2) Почему я не могу получить доступ к свойству, которое дает список DeclaredMethods ()?

1 Ответ

3 голосов
/ 16 апреля 2019

Попробуйте это:

Function GetClassMethods(ByVal theType As Type) As List(Of String)
    Dim flags = Reflection.BindingFlags.Instance Or Reflection.BindingFlags.Public Or Reflection.BindingFlags.DeclaredOnly
    Dim result = theType.GetMethods(flags).
          Where(Function(m)  Not m.IsSpecialName).
          Select(Function(m) m.Name)
    Return result.ToList()
End Function

или для развлечения с дженериками:

Function GetClassMethods(Of T)() As List(Of String)
    Dim flags = Reflection.BindingFlags.Instance Or Reflection.BindingFlags.Public Or Reflection.BindingFlags.DeclaredOnly
    Dim result = GetType(T).GetMethods(flags).
          Where(Function(m)  Not m.IsSpecialName).
          Select(Function(m) m.Name)
    Return result.ToList()
End Function

Фильтр IsSpecialName исключает методы с именами, сгенерированными компилятором, такие как специальные методы, используемые компилятором для реализации свойств. Вы также можете поиграть с флагами больше, если вам нужно включить, скажем, и непубличных участников.


Наконец, когда у вас есть метод, заканчивающийся на Return something.ToList() (или который может закончиться этим, как показывает моя адаптация), почти всегда лучше изменить метод, чтобы он возвращал IEnumerable(Of T) вместо и позвольте вызывающему коду позвонить ToList(), если это действительно необходимо. Так что мой первый пример выше действительно так:

Function GetClassMethods(ByVal theType As Type) As IEnumerable(Of String)
    Dim flags = Reflection.BindingFlags.Instance Or Reflection.BindingFlags.Public Or Reflection.BindingFlags.DeclaredOnly
    Return theType.GetMethods(flags).
          Where(Function(m)  Not m.IsSpecialName).
          Select(Function(m) m.Name)
End Function

Эй, это может быть однострочник. Тогда для тех ситуаций, когда вам действительно нужен список, вы можете сделать это:

Dim methodNames As List(Of String) = GetClassMethods(HomeController).ToList()

Вы начнете находить во многих ситуациях, что вам вообще не нужно использовать ToList(); универсальный IEnumerable был достаточно хорош. Конечно, это верно везде, где вы просто используете результат с циклом For Each. Теперь внезапно использование памяти в ваших программах значительно уменьшилось.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...