Search code examples
c#.net-assemblysystem.reflection

Get only the current class members via Reflection


Assume this chunk of code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Reflection;

namespace TestFunctionality
{
  class Program
  {
    static void Main(string[] args)
    {
      // System.Reflection.Assembly.GetExecutingAssembly().Location
      Assembly assembly = Assembly.LoadFrom("c:\\testclass.dll");
      AppDomain.CurrentDomain.Load(assembly.GetName());
      var alltypes = assembly.GetTypes();
      foreach (var t in alltypes)
      {
        Console.WriteLine(t.Name);
        var methods = t.GetMethods(/*BindingFlags.DeclaredOnly*/);
        foreach (var method in methods)
        Console.WriteLine(
        "\t--> "
        +(method.IsPublic? "public ":"")
        + (method.IsPrivate ? "private" : "") 
        + (method.IsStatic ? "static " : "") 
        + method.ReturnType + " " + method.Name);
      }
      Console.ReadKey();
    }
  }
}

I am trying to get the definition of methods that are defined in this class but not from the base class. ie, I don't want to get things like

System.String ToString() // A method in the base class object.

How can I filter them out?

I tried to pass BindingFlags.DeclaredOnly but that filters everything. This is inside testclass.dll :

namespace TestClass
{
public class Class1
    {
      public static int StaticMember(int a) { return a; }
      private void privateMember() { }
      private static void privateStaticMember() { }
      public void PublicMember() { }
      public void PublicMember2(int a) { }
      public int PublicMember(int a) { return a; }
    }
}

What do you suggest?

Thank you.


Solution

  • You want this:

    cl.GetMethods(BindingFlags.DeclaredOnly |
        BindingFlags.Instance |
        BindingFlags.Public);
    

    Per the MSDN documentation it states that DeclaredOnly:

    Specifies that only members declared at the level of the supplied type's hierarchy should be considered. Inherited members are not considered.

    Now, maybe you explicitly want methods that aren't public:

    cl.GetMethods(BindingFlags.DeclaredOnly |
        BindingFlags.Instance |
        BindingFlags.NonPublic);
    

    If you want both public and non-public method, do this:

    cl.GetMethods(BindingFlags.DeclaredOnly |
        BindingFlags.Instance |
        BindingFlags.Public |
        BindingFlags.NonPublic);
    

    Notice that each query contains Instance and Public or NonPublic, that's because the documentation states the following:

    You must specify Instance or Static along with Public or NonPublic or no members will be returned.