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

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

ExpandedBlockStart.gif ContractedBlock.gif         /**/ /// <summary>
InBlock.gif        
/// 正常方法
ExpandedBlockEnd.gif        
/// </summary>

None.gif          static   void  Method1()
ExpandedBlockStart.gifContractedBlock.gif        
dot.gif {
InBlock.gif            DisabledObsoleteMethod();
ExpandedBlockEnd.gif        }

None.gif
ExpandedBlockStart.gifContractedBlock.gif        
/**/ /// <summary>
InBlock.gif        
/// 过期方法
ExpandedBlockEnd.gif        
/// </summary>

None.gif         [Obsolete]
None.gif        
static   void  Method2()
ExpandedBlockStart.gifContractedBlock.gif        
dot.gif {
InBlock.gif            DisabledObsoleteMethod();
ExpandedBlockEnd.gif        }

None.gif
ExpandedBlockStart.gifContractedBlock.gif        
/**/ /// <summary>
InBlock.gif        
/// 禁止过期方法调用此方法
ExpandedBlockEnd.gif        
/// </summary>

None.gif          static   void  DisabledObsoleteMethod()
ExpandedBlockStart.gifContractedBlock.gif        
dot.gif {
InBlock.gif            
//如果调用此方法的方法中有"Obsolete"标记则不允许继续运行
ExpandedBlockEnd.gif
        }


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

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

ExpandedBlockStart.gif ContractedBlock.gif          /**/ /// <summary>
InBlock.gif        
/// 禁止过期方法调用此方法
ExpandedBlockEnd.gif        
/// </summary>

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

InBlock.gif
InBlock.gif            
//继续做其它操作
ExpandedBlockEnd.gif
        }


到此,当运行Method1时我们的DisabledObsoleteMethod函数就可以正常运作,而Method2就会被抛出异常警告了 49_49.gif


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

None.gif      class  Test
ExpandedBlockStart.gifContractedBlock.gif    
dot.gif {
InBlock.gif        
static void Main()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
int offset = 0;
InBlock.gif            
do
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                StackFrame frame 
= new StackFrame(offset++);
InBlock.gif                MethodBase method 
= frame.GetMethod();
InBlock.gif                
if (method == nullbreak;       //如果偏移位置没有函数时,则GetMethod方法返回null
InBlock.gif
                Console.WriteLine(method.Name);
InBlock.gif
ExpandedSubBlockEnd.gif            }
 while (true);
InBlock.gif            Console.Read();
ExpandedSubBlockEnd.gif        }

ExpandedBlockEnd.gif    }


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

None.gif     class  Test
ExpandedBlockStart.gifContractedBlock.gif    
dot.gif {
InBlock.gif        
static void Main()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            StackTrace trace 
= new StackTrace();
InBlock.gif            
foreach (StackFrame frame in trace.GetFrames())
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                Console.WriteLine(frame.GetMethod().Name);
ExpandedSubBlockEnd.gif            }

InBlock.gif            Console.Read();
ExpandedSubBlockEnd.gif        }

ExpandedBlockEnd.gif    }


两者输出的结果还是一样的 shades_smile.gif,如下:

None.gif Main
None.gif_nExecuteAssembly
None.gifExecuteAssembly
None.gifRunUsersAssembly
None.gifThreadStart_Context
None.gifRun
None.gifThreadStart

看来在控制台程序中也是由某个线程委托开始运作的 75_75.gif
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值