Вопрос по .net, c#, reflection – Как найти полное имя вызывающего метода C #

18

Как я могу найти полное имя вызывающего метода в C #. Я видел решения:

Как я могу получить вызывающие методы в C #

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

Получить имя вызывающей функции из вызываемой функции

Но они только дают мне высший уровень. Рассмотрим пример:

namespace Sandbox
{
    class Program
    {
        static void Main(string[] args)
        {
            test();
        }

        static void test()
        {
            var stackTrace = new StackTrace();
            var methodBase = stackTrace.GetFrame(1).GetMethod();
            Console.WriteLine(methodBase.Name);
        }
    }
}

Это просто выводит «Main» Как я могу заставить его напечатать «Sandbox.Program.Main»?

Прежде чем кто-либо начнет спрашивать, почему мне нужно это использовать, это для простой среды ведения журналов, над которой я работаю.

EDIT

Добавление к ответу Маци:

Вот решение:

namespace Sandbox
{
    class Program
    {
        static void Main(string[] args)
        {
            test();
        }

        static void test()
        {
            var stackTrace = new StackTrace();
            var methodBase = stackTrace.GetFrame(1).GetMethod();
            var Class = methodBase.ReflectedType;
            var Namespace = Class.Namespace;         //Added finding the namespace
            Console.WriteLine(Namespace + "." + Class.Name + "." + methodBase.Name);
        }
    }
}

Создает "Sandbox.Program.Main" как должно

возможный дубликатUsing System.Reflection to Get a Method's Full Name user7116

Ваш Ответ

5   ответов
4

 this.GetType().FullName + "." + System.Reflection.MethodBase.GetCurrentMethod().Name;

или попробуйте это

string method = string.Format("{0}.{1}", MethodBase.GetCurrentMethod().DeclaringType.FullName, MethodBase.GetCurrentMethod().Name);  

и если вы хотите отобразить самый последний вызов функции, вы можете использовать:

StackTrace st  = new StackTrace(); 
StackFrame sf  = st.GetFrame(0);
var methodName = sf.GetMethod();

, но если вы хотите отобразить дерево вызывающих функций, вы можете сделать это так:

if (st.FrameCount >1)
{
     // Display the highest-level function call 
     // in the trace.
     StackFrame sf = st.GetFrame(st.FrameCount-1);
     Console.WriteLine("  Original function call at top of call stack):");
     Console.WriteLine("      {0}", sf.GetMethod());
}

для большегоИнформация

Это возвращает имя текущего метода, а не вызывающего метода, как хочет OP
да, вы правы, если вы хотите отобразить самый последний вызов функции, вы можете использовать: StackTrace st = new StackTrace (); st.GetFrame (0); , но если вы хотите отобразить дерево вызывающих функций, вы можете сделать это следующим образом: if (st.FrameCount & gt; 1) {// Показать вызов функции самого высокого уровня // в трассировке. StackFrame sf = st.GetFrame (st.FrameCount-1); Console.WriteLine (& quot; Исходный вызов функции на вершине стека вызовов): & quot;); Console.WriteLine (& quot; {0} & quot ;, sf.GetMethod ()); }msdn.microsoft.com/en-us/library/…
0

    public void HandleException(Exception ex, [CallerMemberName] string caller = "")
    {
        if (ex != null)
        {
            while (ex.InnerException != null)
                ex = ex.InnerException;

            foreach (var method in new StackTrace().GetFrames())
            {
                if (method.GetMethod().Name == caller)
                {
                    caller = $"{method.GetMethod().ReflectedType.Name}.{caller}";
                    break;
                }
            }

            Console.WriteLine($"Exception: {ex.Message} Caller: {caller}()");
        }
    }
0

которое не равно текущему пространству имен

    var mNamespace = new StackTrace().GetFrames()?.Select(x =>
                {
                    try
                    {
                        return x.GetMethod().ReflectedType?.Namespace;
                    }
                    catch (Exception)
                    {
                        return string.Empty;
                    }
                }).First(x => x != new StackTrace().GetFrame(0).GetMethod().ReflectedType?.Namespace);
0

System.Reflection.MethodBase методGetCurrentMethod Вы можете найти полную информацию о callstack, используя классы и т. д.

Как?GetCurrentMethod возвращаетMethodBase который, кажется, не раскрывает ничего о трассировке стека (кроме текущего типа).
29

Вот.

MethodBase method = stackTrace.GetFrame(1).GetMethod();
string methodName = method.Name;
string className = method.ReflectedType.Name;

Console.WriteLine(className + "." + methodName);
@Matzi - Это сделало мою жизнь такой легкой. Идеальный ответ!
Спасибо! Я отредактировал вопрос только для того, чтобы добавить, как я решил найти пространство имен. Adam Schiavone
Не работает. Метод может быть не вызывающим, но одним из внешних: вызывающий метод может больше не существовать, т. Е. Был встроен.
Можно ли также получить вложенные классы? Если я сделал класс внутри Program, давайте назовем егоFooИ у меня есть метод вFoo (давайте назовем этоBar) вызовProgram.test() Это должно напечататьSandbox.Program.Foo.Bar Adam Schiavone
@ TomTom, я действительно не знаю (поскольку это может быть очень неправильно!), Но если он был встроен, то в MSIL он не существует как «метод». Я не знаю, как метод времени выполнения сможет получить то, что существует только перед компиляцией.

Похожие вопросы