开发手册 欢迎您!
软件开发者资料库

.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文件,否则就只能返回0Console.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('-', '>');

}