In this article, we will look into how can we figure out only User Defined Methods from a Class using Reflection.
Introduction
If we want to glean the information about a class or Assembly at runtime,to add properties/methods etc. to the class/assembly at runtime or dynamically,the only way to perform this is the Reflection mechanism. In dotnet, we use the System.Reflection namespace which contains all the needed methods for achieving the work. In this article, we will look into how can we figure out only User-Defined Methods from a Class using Reflection.
Initial Setup
First of all, let us create a class as under
public class Employee
{
public int EmployeeId { get; set; }
public string EmployeeName { get; set; }
public void Display()
{
Console.WriteLine("{0} {1}", EmployeeId, EmployeeName);
}
public string DisplayFormattedMesage(string message)
{
return string.Concat(message, " ", EmployeeName);
}
private int GetEmployeeID()
{
return EmployeeId;
}
private static int GetStaticEmployeeID()
{
return 123456;
}
[DllImport("kernel32.dll")]
public static extern bool AnExternMethod(int ferequency, int duration);
}
Using the code
As can be figure out that, it is a typical class that we encounter almost every day , with two properties namely EmployeeId and EmployeeName and a few methods some are public, private, static and extern. Now let us execute the below program.
using System;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
//Get all the public,private, static and instance members of the Employee class using the //GetMethods of using System.Reflection
var methodInfos = typeof(Employee).GetMethods(
BindingFlags.Public |
BindingFlags.NonPublic |
BindingFlags.Instance |
BindingFlags.Static
).ToList();
//print the methods
foreach (var methodInfo in methodInfos) Console.WriteLine(methodInfo.Name);
Console.Read();
}
}
}
The result

But our intention is to get only the user-defined methods.So let's see how it can be achieve.Before going to write the program segment, lets look into the System.Object class.

We can figure out that Equals,GetHashCode and ToString are virtual.We can eliminate them easily by putting a filtering condition by using the read-only property IsVirtual of the MethodBase class.
The IsVirtual states :

foreach (var methodInfo in methodInfos)
{
if (!methodInfo.IsVirtual) //eliminate the Virtual Methods of the System.Object
Console.WriteLine(methodInfo.Name);
}
The result

Now we are left with GetType and MemberwiseClone. There is a read-only property under MethodBase class by the name MethodImplementationFlags. It
Gets the System.Reflection.MethodImplAttributes flags that specify the attributes of a method implementation.
The MethodImplAttributes is an Enum that specifies flags for the attributes of a method implementation.
For the case of GetType and MemberwiseClone, the MethodImplementationFlags is of the MethodImplAttributes Enum InternalCall. Hence, the below will do the work
//print the methods
foreach (var methodInfo in methodInfos)
{
if (!methodInfo.IsVirtual)
{
if (methodInfo.MethodImplementationFlags != MethodImplAttributes.InternalCall)
Console.WriteLine(methodInfo.Name);
}
}

Now we need to eliminate the getter and setter properties.Before going to say anything, we would like to show what the IL says

Double click on get_EmployeeId:int32() and we will find

Observe the SpecialName bit - It indicates that the method is special. So,in this case, there is a property call IsSpecialName, which is set to True. The trick is to filter out those methods where the IsSpecialName is "False"
//print the methods
foreach (var methodInfo in methodInfos)
{
//eliminate the virtual methods of the System.Object class
if (!methodInfo.IsVirtual)
{
//eliminate the InternalCall of the System.Object class
if (methodInfo.MethodImplementationFlags != MethodImplAttributes.InternalCall)
{
//eliminate the SpecialNames methods like properties
if (!methodInfo.IsSpecialName)
{
Console.WriteLine(methodInfo.Name);
}
}
}
}
And here we go

So we achieve our target.Below is a lambda version of the same
//The lambda version
methodInfos
.Where(m => !m.IsSpecialName && !m.IsVirtual && m.MethodImplementationFlags != MethodImplAttributes.InternalCall)
.ToList()
.ForEach(i => Console.WriteLine(i.Name));
But is it the only way? Cannot it be done in a much better way? Yes - of-course! The BindingFlags has a member DeclaredOnly. It says
Specifies that only members declared at the level of the supplied type's hierarchy should be considered. Inherited members are not considered.
So let us modify our program as under
typeof(Employee)
.GetMethods(
BindingFlags.Public |
BindingFlags.NonPublic |
BindingFlags.Instance |
BindingFlags.Static |
BindingFlags.DeclaredOnly
)
.ToList()
.ForEach(i => Console.WriteLine(i.Name));
The output

Now we know what to do
typeof(Employee)
.GetMethods(
BindingFlags.Public |
BindingFlags.NonPublic |
BindingFlags.Instance |
BindingFlags.Static |
BindingFlags.DeclaredOnly
)
.Where(m => !m.IsSpecialName )
.ToList()
.ForEach(i => Console.WriteLine(i.Name));
References
Reflection in C# Tutorial
Conclusion
Hope you will find this useful.Thanks for reading the article.Please find the zipped file attached herewith.