且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

让您知道您的方法是被何“人”调用

更新时间:2022-09-25 20:27:27

也许在某些场合下我们想知道自己的某个方法是被谁(哪个方法)调用的?比如下面的例子:

让您知道您的方法是被何“人”调用       /// <summary>
让您知道您的方法是被何“人”调用        
/// 正常方法
让您知道您的方法是被何“人”调用        
/// </summary>

让您知道您的方法是被何“人”调用        static void Method1()
让您知道您的方法是被何“人”调用        
{
让您知道您的方法是被何“人”调用            DisabledObsoleteMethod();
让您知道您的方法是被何“人”调用        }

让您知道您的方法是被何“人”调用
让您知道您的方法是被何“人”调用        
/// <summary>
让您知道您的方法是被何“人”调用        
/// 过期方法
让您知道您的方法是被何“人”调用        
/// </summary>

让您知道您的方法是被何“人”调用        [Obsolete]
让您知道您的方法是被何“人”调用        
static void Method2()
让您知道您的方法是被何“人”调用        
{
让您知道您的方法是被何“人”调用            DisabledObsoleteMethod();
让您知道您的方法是被何“人”调用        }

让您知道您的方法是被何“人”调用
让您知道您的方法是被何“人”调用        
/// <summary>
让您知道您的方法是被何“人”调用        
/// 禁止过期方法调用此方法
让您知道您的方法是被何“人”调用        
/// </summary>

让您知道您的方法是被何“人”调用        static void DisabledObsoleteMethod()
让您知道您的方法是被何“人”调用        
{
让您知道您的方法是被何“人”调用            
//如果调用此方法的方法中有"Obsolete"标记则不允许继续运行
让您知道您的方法是被何“人”调用
        }


在上面代码中,我们要在DisabledObsoleteMethod函数里限制具有“Obsolete”属性的方法调用,我们如何去做呢?

在.Net中提供了一个"StackFrame"类用于表示当前线程上的函数调用堆栈中的某个具体函数,所以我们通过它就可继续编写我们的DisabledObsoleteMethod函数,代码如下:

让您知道您的方法是被何“人”调用        /// <summary>
让您知道您的方法是被何“人”调用        
/// 禁止过期方法调用此方法
让您知道您的方法是被何“人”调用        
/// </summary>

让您知道您的方法是被何“人”调用        static void DisabledObsoleteMethod()
让您知道您的方法是被何“人”调用        
{
让您知道您的方法是被何“人”调用            StackFrame frame 
= new StackFrame(1);       //偏移一个函数位,也即是获取当前函数的前一个调用函数
让您知道您的方法是被何“人”调用
            MethodBase method = frame.GetMethod();      //取得调用函数
让您知道您的方法是被何“人”调用            
//反射获取其特性
让您知道您的方法是被何“人”调用
            object[] attributes = method.GetCustomAttributes(typeof(ObsoleteAttribute), false);
让您知道您的方法是被何“人”调用            
if (attributes.Length > 0)
让您知道您的方法是被何“人”调用            
{
让您知道您的方法是被何“人”调用                
//包含有"Obsolete"标记抛出错误或做其它处理
让您知道您的方法是被何“人”调用
                throw new Exception(string.Format("方法{0}包括有Obsolete属性已被禁止调用",method.Name));
让您知道您的方法是被何“人”调用            }

让您知道您的方法是被何“人”调用
让您知道您的方法是被何“人”调用            
//继续做其它操作
让您知道您的方法是被何“人”调用
        }


到此,当运行Method1时我们的DisabledObsoleteMethod函数就可以正常运作,而Method2就会被抛出异常警告了让您知道您的方法是被何“人”调用


因为StackFrame的构造函数可以指定偏移量,所以我们可以使用它获取调用我们的函数时函数调用堆栈里都有些什么函数,也即是可以了解到当前程序的一个流程是如何的,示例代码如下:

让您知道您的方法是被何“人”调用    class Test
让您知道您的方法是被何“人”调用    
{
让您知道您的方法是被何“人”调用        
static void Main()
让您知道您的方法是被何“人”调用        
{
让您知道您的方法是被何“人”调用            
int offset = 0;
让您知道您的方法是被何“人”调用            
do
让您知道您的方法是被何“人”调用            
{
让您知道您的方法是被何“人”调用                StackFrame frame 
= new StackFrame(offset++);
让您知道您的方法是被何“人”调用                MethodBase method 
= frame.GetMethod();
让您知道您的方法是被何“人”调用                
if (method == nullbreak;       //如果偏移位置没有函数时,则GetMethod方法返回null
让您知道您的方法是被何“人”调用
                Console.WriteLine(method.Name);
让您知道您的方法是被何“人”调用
让您知道您的方法是被何“人”调用            }
 while (true);
让您知道您的方法是被何“人”调用            Console.Read();
让您知道您的方法是被何“人”调用        }

让您知道您的方法是被何“人”调用    }


其实.NET已经为我们提供了一个StackTrace类,其可以获取函数调用堆栈里的所有函数的有序集合,通过它我们就能将上面的代码简化为下面的代码了,如下:

让您知道您的方法是被何“人”调用   class Test
让您知道您的方法是被何“人”调用    
{
让您知道您的方法是被何“人”调用        
static void Main()
让您知道您的方法是被何“人”调用        
{
让您知道您的方法是被何“人”调用            StackTrace trace 
= new StackTrace();
让您知道您的方法是被何“人”调用            
foreach (StackFrame frame in trace.GetFrames())
让您知道您的方法是被何“人”调用            
{
让您知道您的方法是被何“人”调用                Console.WriteLine(frame.GetMethod().Name);
让您知道您的方法是被何“人”调用            }

让您知道您的方法是被何“人”调用            Console.Read();
让您知道您的方法是被何“人”调用        }

让您知道您的方法是被何“人”调用    }


两者输出的结果还是一样的让您知道您的方法是被何“人”调用,如下:

让您知道您的方法是被何“人”调用Main
让您知道您的方法是被何“人”调用_nExecuteAssembly
让您知道您的方法是被何“人”调用ExecuteAssembly
让您知道您的方法是被何“人”调用RunUsersAssembly
让您知道您的方法是被何“人”调用ThreadStart_Context
让您知道您的方法是被何“人”调用Run
让您知道您的方法是被何“人”调用ThreadStart

看来在控制台程序中也是由某个线程委托开始运作的让您知道您的方法是被何“人”调用
本文转自Kingthy博客园博客,原文链接:http://www.cnblogs.com/kingthy/archive/2008/04/19/1160816.html,如需转载请自行联系原作者