Alan
Alan

Reputation: 1637

Can't get a list of declared methods in a .net class

Having read a great many posts on using reflection to get a list of methods in a given class, I am still having trouble getting that list and need to ask for help. This is my current code:

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

I call this method like this:

GetClassMethods(GetType(HomeController))

The return has 43 methods, but I only want the methods I wrote in the class. The image below shows the beginning of what was returned. My declared methods are in this list, but down at location 31-37. There are actually 9 declared methods, but this list doesn’t show the Private methods.

enter image description here

When I look at theType, I see the property I want. It is DeclaredMethods which shows every declared method, public and private.

enter image description here

However, I’m not able to access this property with a statement such as this.

Dim methodList = theType.DeclaredMethods

The returned error is that DelaredMethods is not a member of Type. So, my questions are multiple:

1) Most important, what code do I need to retrieve every declared method in the class, and only the methods I declared?

2) Why am I not able to access the property that gives the list of DeclaredMethods()?

Upvotes: 0

Views: 442

Answers (1)

Joel Coehoorn
Joel Coehoorn

Reputation: 416149

Try this:

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

or for some fun with generics:

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

The IsSpecialName filter excludes methods with compiler-generated names, such as the special methods used by the compiler to implement properties. You can also play around more with the flags if you need to include, say, NonPublic members as well.


Finally, whenever you have a method ending with Return something.ToList() (or which could end with it, as my adaption shows here), it's almost always better to change the method to return an IEnumerable(Of T) instead, and let the calling code call ToList() if it really needs it. So my first example above is really better like this:

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

Hey, that could be a single-liner. Then for those situations where you really need a list, you can do this:

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

You'll start to find in many situations you don't need to use ToList() at all; the generic IEnumerable was good enough. Certainly this is true anywhere you just use the result with For Each loop. Now suddenly the memory use in your programs are significantly reduced.

Upvotes: 4

Related Questions