Как получить имя и тип вызывающего метода с помощью отражения?

Возможный дубликат:
Как я могу найти метод, который вызвал текущий метод?

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

Возможно ли это с помощью отражения C#?

5 ответов

Решение
public class SomeClass
{
    public void SomeMethod()
    {
        StackFrame frame = new StackFrame(1);
        var method = frame.GetMethod();
        var type = method.DeclaringType;
        var name = method.Name;
    }
}

Теперь предположим, что у вас есть другой класс, подобный этому:

public class Caller
{
   public void Call()
   {
      SomeClass s = new SomeClass();
      s.SomeMethod();
   }
}

имя будет "Call", а тип будет "Caller"

ОБНОВЛЕНИЕ Два года спустя, так как я все еще получаю голоса против этого

В.Net 4.5 теперь есть гораздо более простой способ сделать это. Вы можете воспользоваться CallerMemberNameAttribute

Переходя к предыдущему примеру:

public class SomeClass
{
    public void SomeMethod([CallerMemberName]string memberName = "")
    {
        Console.WriteLine(memberName); //output will be name of calling method
    }
}

Вы можете использовать его с помощью StackTrace и тогда вы можете получить отражающие типы из этого.

StackTrace stackTrace = new StackTrace();           // get call stack
StackFrame[] stackFrames = stackTrace.GetFrames();  // get method calls (frames)

StackFrame callingFrame = stackFrames[1];
MethodInfo method = callingFrame.GetMethod();
Console.Write(method.Name);
Console.Write(method.DeclaringType.Name);

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

public void MyMethod()
{
     StackTrace stackTrace = new System.Diagnostics.StackTrace();
     StackFrame frame = stackTrace.GetFrames()[1];
     MethodInfo method = frame.GetMethod();
     string methodName = method.Name;
     Type methodsClass = method.DeclaringType;
}

1 индекс на StackFrame массив даст вам метод, который называется MyMethod

Технически, вы можете использовать StackTrace, но это очень медленно и не даст вам ответов, которые вы ожидаете большую часть времени. Это связано с тем, что во время сборок выпуска могут происходить оптимизации, которые удаляют определенные вызовы методов. Следовательно, вы не можете быть уверены в выпуске, является ли трассировка стека "правильной" или нет.

На самом деле, нет никакого надежного или быстрого способа сделать это в C#. Вы действительно должны спросить себя, зачем вам это нужно и как вы можете спроектировать свое приложение, чтобы вы могли делать то, что вы хотите, не зная, какой метод вызвал это.

Да, в принципе это возможно, но это не бесплатно.

Вам нужно создать StackTrace, а затем вы можете взглянуть на StackFrame стека вызовов.

Другие вопросы по тегам