Получить только текущих членов класса через Reflection

Предположим, что этот фрагмент кода:

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();
    }
  }
}

Я пытаюсь получить определение методов, определенных в этом классе, но не из базового класса. т.е. я не хочу получать такие вещи, как

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

Как я могу отфильтровать их?

Я пытался передать BindingFlags.DeclaredOnly, но это все фильтрует. Это внутри 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; }
    }
}

Что ты предлагаешь?

Спасибо.


person Aaron Azhari    schedule 08.05.2014    source источник


Ответы (2)


Вы хотите это:

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

В документации MSDN указано, что DeclaredOnly :

Указывает, что следует учитывать только элементы, объявленные на уровне иерархии предоставленного типа. Унаследованные члены не учитываются.

Теперь, возможно, вам явно нужны методы, которые не являются public:

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

Если вам нужны оба public и не public метода, сделайте следующее:

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

Обратите внимание, что каждый запрос содержит Instance и Public или NonPublic, потому что в документации указано следующее:

Вы должны указать Экземпляр или Статический вместе с Общедоступный или Непубличный, иначе члены не будут возвращены. сильный>.

person Mike Perrenoud    schedule 08.05.2014
comment
+1 Примечание. Для закрытых участников это поведение по умолчанию. Вы получите только объявленных участников. - person Sriram Sakthivel; 08.05.2014
comment
@SriramSakthivel, подождите, а NonPublic не захватит ли еще protected участников? Они будут унаследованы. - person Mike Perrenoud; 08.05.2014
comment
Должен признаться, я подумывал о том, чтобы удержать +1 за использование этой фразы. Варианты довольно безграничны. Я уверен, что вариантов не больше миллиона... ;-) - person Chris; 08.05.2014
comment
@MichaelPerrenoud Я не думаю, что protected будет восстановлен. лень тестить. Я думаю, это верно для всех непубличных. - person Sriram Sakthivel; 08.05.2014
comment
когда я использую DeclaredOnly, я не получаю ничего, кроме имени класса. Я обновил вопрос, чтобы показать лучший пример кода. - person Aaron Azhari; 08.05.2014
comment
@AramAzhari, пожалуйста, посмотрите мое редактирование. Всегда требуются два обязательных флага: Instance или Static и Public или NonPublic, пожалуйста, примите мои извинения. - person Mike Perrenoud; 08.05.2014
comment
Спасибо за разъяснение этого. Я также добавил static, поэтому я тоже получаю эти методы. Вот что у меня получилось, чтобы это сработало: BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic - person Aaron Azhari; 08.05.2014
comment
@AramAzhari, ты понял, друг! Теперь вы получаете более абстрактную концепцию. - person Mike Perrenoud; 08.05.2014

Я думаю, вам нужен флаг привязки DeclaredOnly

person DJL    schedule 08.05.2014