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

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

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

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

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

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

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

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


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

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

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

None.gif          static   void  DisabledObsoleteMethod()
ExpandedBlockStart.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.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.gif    
{
InBlock.gif        
static void Main()
ExpandedSubBlockStart.gif        
{
InBlock.gif            
int offset = 0;
InBlock.gif            
do
ExpandedSubBlockStart.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.gif    
{
InBlock.gif        
static void Main()
ExpandedSubBlockStart.gif        
{
InBlock.gif            StackTrace trace 
= new StackTrace();
InBlock.gif            
foreach (StackFrame frame in trace.GetFrames())
ExpandedSubBlockStart.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
本文转自Kingthy博客园博客,原文链接:http://www.cnblogs.com/kingthy/archive/2008/04/19/1160816.html ,如需转载请自行联系原作者
相关文章
|
24天前
|
C语言 C++ 容器
C调用C++代码
C调用C++代码
12 1
|
10月前
|
存储 数据处理 数据库
结构化分析方法
1.概述 结构化方法是世界上第一个软件开发方法学,用来指导从需求分析、到设计开发各个阶段该怎么样做,采用什么样的方法,产出什么样的结果,从而保证整个软件开发周期可控。
84 0
|
存储 C语言 容器
调用一个函数时发生了什么?
调用一个函数时发生了什么?
76 0
调用一个函数时发生了什么?
|
缓存 负载均衡 微服务
多服务间的调用
上文我们把我们项目注册到服务器上了,但是在微服务中,我们会有多个服务,同时也会使用A服务调用B服务的接口。springcloud netflix这里有两种方式ribbon和feign,我们分别介绍。
98 0
多服务间的调用
想求问一下,瑜伽的练习方法
沐鸣如果勉强坐得太久,很容易因为身体酸麻涨痛而对瑜伽坐姿练习发生退却之心,所以最初练习以“短时多次”为宜,慢慢就能享受到打坐的乐趣了练习瑜伽坐姿时,要坚持腰背挺直,下颗内收,使头部、颈部和脊椎保持在一条直线上。此外,练习全莲花坐时,注意膝盖不要上浮。>
|
C++
c调用c++函数
c调用c++普通函数     cpp_test/cpp.h #ifndef CPP_H #define CPP_H #include "extern_cpp.h" int add(int a, int b); char add(char a, char b); #endif // CPP_H     cpp_test/extern_cpp.
1984 0
Egiht(八种方法)
Problem Description The 15-puzzle has been around for over 100 years; even if you don't know it by that name, you've seen it.
1267 0
|
存储 算法 搜索推荐
常用的外部排序方法
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_34173549/article/details/81158566 定义问题       外部排序指的是大文件的排序,即待排序的记录存储在外存储器上,待排序的文件无法一次装入内存,需要在内存和外部存储器之间进行多次数据交换,以达到排序整个文件的目的。
1752 0
|
测试技术 C#
分享几个实用的方法
  今天主要和大家分享的是本人总结的分页执行方法,也可以说就是分批执行;该篇采用java8新增的表达式来操作,希望能给各位带来好的帮助和在日常工作中提供便利;同样的操作流程和逻辑之前用C#代码写过一次,有需要的朋友可以看以前的博文; 分页方式拆分List为多个子集List方法 执行统一方法-无...
1176 0
|
Java 开发工具 应用服务中间件