Reputation: 1637
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.
When I look at theType
, I see the property I want. It is DeclaredMethods
which shows every declared method, public and private.
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
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