.Net Core(C#) 使用StackTrace或StackFrame获取方法的调用者方法所在类的类名

本文主要介绍.Net Core(C#)中,当一个类一个方法会被其它类的某个方法调用时,使用StackTrace或StackFrame获取调用者方法的类名,也就是这个其它类的类名的示例代码,以及使用StackTrace获取堆栈信息(文件名、行号、函数名、列号)的方法。

1、使用StackTrace实现

using System;
using System.Diagnostics;
namespace demo
{
    public class OtherClass
    {
        public void OtherMethod()
        {
            string callerClassName = new StackFrame(1).GetMethod().DeclaringType.Name;
            string callerClassNameWithNamespace = new StackFrame(1).GetMethod().DeclaringType.FullName;
            Console.WriteLine("调用者方法:" + callerClassName);
            Console.WriteLine("This is the only name of your class with its namespace:" + callerClassNameWithNamespace);
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            new OtherClass().OtherMethod();
            Console.WriteLine("Hello World!"); ;
        }
    }
}

输出结果:

调用者方法所在类的类名:Program
调用者方法所在类的带有命名空间的类名:demo.Program

2、使用StackFrame实现

using System;
using System.Diagnostics;
namespace demo
{
    public class OtherClass
    {
        public void OtherMethod()
        {
            string callerClassName = new StackFrame(1).GetMethod().DeclaringType.Name;
            string callerClassNameWithNamespace = new StackFrame(1).GetMethod().DeclaringType.FullName;
            OtherClass.GetStackTraceModelName();
            Console.WriteLine("调用者方法所在类的类名:" + callerClassName);
            Console.WriteLine("调用者方法所在类的带有命名空间的类名:" + callerClassNameWithNamespace);
        }
      public  static string GetStackTraceModelName()
        {
            //当前堆栈信息
            System.Diagnostics.StackTrace st = new System.Diagnostics.StackTrace();
            System.Diagnostics.StackFrame[] sfs = st.GetFrames();
            //过虑的方法名称,以下方法将不会出现在返回的方法调用列表中
            string _filterdName = "ResponseWrite,ResponseWriteError,";
            string _fullName = string.Empty, _methodName = string.Empty;
            for (int i = 1; i < sfs.Length; ++i)
            {
                //非用户代码,系统方法及后面的都是系统调用,不获取用户代码调用结束
                if (System.Diagnostics.StackFrame.OFFSET_UNKNOWN == sfs[i].GetILOffset()) break;
                _methodName = sfs[i].GetMethod().Name;//方法名称
                                                      //sfs[i].GetFileLineNumber();//没有PDB文件的情况下将始终返回0
                if (_filterdName.Contains(_methodName)) continue;
                _fullName = _methodName + "()->" + _fullName;
                Console.WriteLine(" File: {0}", sfs[i].GetFileName());                                                //文件名
                Console.WriteLine(" Method: {0}", sfs[i].GetMethod().Name);                                 //函数名
                Console.WriteLine(" Line Number: {0}", sfs[i].GetFileLineNumber());                  //文件行号,需要项目有调试需要的PDB文件,否则就返回0
                Console.WriteLine(" Column Number: {0}", sfs[i].GetFileColumnNumber());
                Console.WriteLine(" DeclaringType FullName: {0}", sfs[i].GetMethod().DeclaringType.FullName);
            }
            st = null;
            sfs = null;
            _filterdName = _methodName = null;
            return _fullName.TrimEnd('-', '>');
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            new OtherClass().OtherMethod();
            OtherClass.GetStackTraceModelName();
            Console.ReadKey();
        }
    }
}

输出结果:

File:
Method: OtherMethod
Line Number: 0
Column Number: 0
File:
Method: Main
Line Number: 0
Column Number: 0
调用者方法所在类的类名:Program
调用者方法所在类的带有命名空间的类名:demo.Program
File:
Method: Main
Line Number: 0
Column Number: 0

3、使用StackTrace获取堆栈信息(文件名、行号、函数名、列号)

命名空间System.Diagnostics

1) 获取当前的堆栈信息

StackTrace st = new StackTrace(new StackFrame(true));
StackFrame sf = st.GetFrame(0);
Console.WriteLine(" File: {0}", sf.GetFileName());                                                //文件名
Console.WriteLine(" Method: {0}", sf.GetMethod().Name);                                 //函数名
Console.WriteLine(" Line Number: {0}", sf.GetFileLineNumber());                  //文件行号,需要项目有调试需要的PDB文件,否则就只能返回0
Console.WriteLine(" Column Number: {0}", sf.GetFileColumnNumber());

public  static string GetStackTraceModelName()

{

  //当前堆栈信息

  System.Diagnostics.StackTrace st = new System.Diagnostics.StackTrace();

  System.Diagnostics.StackFrame[] sfs = st.GetFrames();

  //过虑的方法名称,以下方法将不会出现在返回的方法调用列表中

  string _filterdName = "ResponseWrite,ResponseWriteError,";

  string _fullName = string.Empty, _methodName = string.Empty;

  for (int i = 1; i < sfs.Length; ++i)

  {

 //非用户代码,系统方法及后面的都是系统调用,不获取用户代码调用结束

 if (System.Diagnostics.StackFrame.OFFSET_UNKNOWN == sfs[i].GetILOffset()) break;

 _methodName = sfs[i].GetMethod().Name;//方法名称

    //sfs[i].GetFileLineNumber();//没有PDB文件的情况下将始终返回0

 if (_filterdName.Contains(_methodName)) continue;

 _fullName = _methodName + "()->" + _fullName;

 Console.WriteLine(" File: {0}", sfs[i].GetFileName());   //文件名

 Console.WriteLine(" Method: {0}", sfs[i].GetMethod().Name);   //函数名

 Console.WriteLine(" Line Number: {0}", sfs[i].GetFileLineNumber());   //文件行号,需要项目有调试需要的PDB文件,否则就返回0

 Console.WriteLine(" Column Number: {0}", sfs[i].GetFileColumnNumber());

 Console.WriteLine(" DeclaringType FullName: {0}", sfs[i].GetMethod().DeclaringType.FullName);

  }

  st = null;

  sfs = null;

  _filterdName = _methodName = null;

  return _fullName.TrimEnd('-', '>');

}

推荐阅读
cjavapy编程之路首页