原文:WPF 判断调用方法堆栈

版权声明:博客已迁移到 http://lindexi.gitee.io 欢迎访问。如果当前博客图片看不到,请到 http://lindexi.gitee.io 访问博客。本文地址 https://blog.csdn.net/lindexi_gd/article/details/78387591

最近遇到一个问题,经常有小伙伴在类A的构造里调用静态函数B,但是这时B依赖于A的初始化完成,于是就无限循环。所以我需要在判断小伙伴调用B时是否在A的构造方法里,如果是就给他异常。

本文告诉大家如何使用 StackTrace 获得调用堆栈,并且判断当前是否构造调用

假设有方法 Foo ,如果需要判断 Foo 的调用有哪些,可以使用下面的代码

        public void Foo()
{
var stackTrace = new StackTrace();
}

使用var n = stackTrace.FrameCount;可以得到当前的栈有几个,最顶部就是最近调用。

例如调用是 lindexi->A->csdn->Foo 那么对应的栈就是下表

序号 方法
3 lindexi
2 A
1 csdn
0 Foo

如果要判断当前的调用是构造函数,那么需要知道,构造函数就是.ctor 那么使用下面的代码就可以判断

            var stackTrace = new StackTrace();
var n = stackTrace.FrameCount;
for (int i = 0; i < n; i++)
{
//判断构造
var cto = ".ctor";
var f = stackTrace.GetFrame(i).GetMethod();
if (f.Name.Equals(cto))
{
Console.WriteLine("构造使用");
}
Console.WriteLine(stackTrace.GetFrame(i).GetMethod().Name);
}

建议把上面的代码复制到一个项目,自己跑一下就知道了

如果还需要判断是指定类型的构造函数,那么需要使用下面的代码,下面代码判断是类型GqpluGkmoanvp的构造调用

        public void Foo()
{
var stackTrace = new StackTrace();
var n = stackTrace.FrameCount;
for (int i = 0; i < n; i++)
{
//判断构造
var cto = ".ctor";
var f = stackTrace.GetFrame(i).GetMethod();
if (f.Name.Equals(cto))
{
var t = f.DeclaringType;
if (t.IsSubclassOf(typeof(GqpluGkmoanvp)) || t == typeof(GqpluGkmoanvp))
{
Console.WriteLine("构造使用");
}
}
Console.WriteLine(stackTrace.GetFrame(i).GetMethod().Name);
}
}
}

实际使用t.IsSubclassOf(typeof(GqpluGkmoanvp))有些多余,但是写了也可以。因为如果写在构造,那么就会先调用基类的构造方法,所以已经会出现判断到基类的构造方法。

例如有下面的类,在构造方法调用Foo,那么调用堆栈就是 Foo-A1-A

public class A1:A
{
public A1()
{
Foo();
}
} public class A
{ }

下面是我封装的一个方法,用于判断当前调用是否在某个类里的某个方法

         /// <summary>
/// 查看调用这个方式是否在某个类的某个方法
/// </summary>
/// <param name="class"></param>
/// <param name="method"></param>
/// <returns></returns>
public static bool CheckStackClassMethod(Type @class, string method)
{
var stackTrace = new StackTrace();
var n = stackTrace.FrameCount;
for (int i = 1; i < n; i++)
{
var f = stackTrace.GetFrame(i).GetMethod();
if (f.Name.Equals(method))
{
var t = f.DeclaringType;
if (t == @class || t.IsSubclassOf(@class) || (@class.IsInterface && @class.IsAssignableFrom(t)))
{
return true;
}
}
}
return false;
}

代码放在WPF 判断调用方法堆栈

因为传入的类型可能是接口,所以类型判断就需要加上接口继承的,所有代码已经给了大家。

使用这个方法,可以把判断是否在某个类的某个方法调用这个函数就可以修改为下面代码

       public void Foo()
{
if (CheckStackClassMethod(typeof(GqpluGkmoanvp), ".d"))
{
Console.WriteLine("构造使用");
}
}

我经过测试下使用这个函数,判断是否我要保护的方法在我不想要被调用的类调用,如果是就抛出异常。接着我的朋友的代码跑不过,就把我祭天。

感谢 walterlv


本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。欢迎转载、使用、重新发布,但务必保留文章署名林德熙(包含链接:http://blog.csdn.net/lindexi_gd ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请与我联系

WPF 判断调用方法堆栈的更多相关文章

  1. 2018-8-10-WPF-判断调用方法堆栈

    title author date CreateTime categories WPF 判断调用方法堆栈 lindexi 2018-08-10 19:16:53 +0800 2018-2-13 17: ...

  2. 基于java.util.logging实现轻量级日志记录库(增加根据当前类class初始化,修复线程池模型(javaEE)下的堆栈轨迹顺序与当前调用方法不一致问题)

    前言: 本章介绍自己写的基于java.util.logging的轻量级日志记录库(baseLog). 该版本的日志记录库犹如其名,baseLog,是个实现日志记录基本功能的小库,适合小型项目使用,方便 ...

  3. .netcore 堆栈调用方法小记

    背景 上午临近午饭时,公司同事反馈验证码被攻击灌水.我们匆忙查询验证码明细,对已频繁出现的IP插入黑名单,但IP仍然隔断时间频繁变动,不得已之下只能先封禁对应公司id的验证码发送功能.年初时候,专门对 ...

  4. C#获取当前堆栈的各调用方法列表

    在使用.NET编写的代码在debug时很容易进行排查和定位问题,一旦项目上线并出现问题的话那么只能依靠系统日志来进行问题排查和定位,但当项目复杂时,即各种方法间相互调用将导致要获取具体的出错方法或调用 ...

  5. XML序列化 判断是否是手机 字符操作普通帮助类 验证数据帮助类 IO帮助类 c# Lambda操作类封装 C# -- 使用反射(Reflect)获取dll文件中的类型并调用方法 C# -- 文件的压缩与解压(GZipStream)

    XML序列化   #region 序列化 /// <summary> /// XML序列化 /// </summary> /// <param name="ob ...

  6. Delphi按名字调用方法高级解决方案

    转帖于https://lfzhs.iteye.com/blog/980200 按名字调用方法似乎一直以来都是大家比较关注的技术,在论坛上有一个经典的答复: type TProcedure = proc ...

  7. WPF 判断一个对象是否是设计时的窗口类型,而不是运行时的窗口

    原文:WPF 判断一个对象是否是设计时的窗口类型,而不是运行时的窗口 当我们对 Window 类型写一个附加属性的时候,在属性变更通知中我们需要判断依赖对象是否是一个窗口.但是,如果直接判断是否是 W ...

  8. 解决:对 PInvoke 函数的调用导致堆栈不对称问题 <转载>

    问题描述: 在使用托管代码调用非托管代码时,发生“对 PInvoke 函数“UseTwiHikVisionDllTest!UseTwiHikVisionDllTest.TwiHikVision::Ge ...

  9. phpcms 的实用相关接口,函数,调用方法

    常用函数 , 打开include/global.func.php,下面存放一些公共函数view plaincopy to clipboardprint? strip_tags() 调用内容过滤html ...

随机推荐

  1. Git 基本使用方法

    Git有一个优点,在本地的每个项目都是一个完整的仓库,除了须要从网络拉取和推送到网络之外,其它全部的操作都能够在本地完毕. 本文简单地介绍怎样在本地使用Git来对文件进行管理,下一篇文章再来说一下分支 ...

  2. php实现运气模型(命运随机,克服困难)

    php实现运气模型(命运随机,克服困难) 一.总结 1.应该用表格来布局的,这种多列的用表格布局比div和span布局方便很多 2.span标签设置宽度:变成行内快元素:display:inline- ...

  3. linux目录架构及常用的基本命令

    linux目录架构 /   根目录 /bin    常用的命令 binary file 的目錄 /boot   存放系统启动时必须读取的档案,包括核心 (kernel) 在内      /boot/g ...

  4. zynq修改ramdisk文件系统

    ⑴ 挂载 Ramdisk新建目录 tmp, 并将 uramdisk.image.gz 拷贝至该目录$ cd <WORKDIR>/Filesystem$ mkdir tmp$ cp uram ...

  5. ios根据字体大小设置

    , , , , , , , , , , , }; //这么多字体,从大到小挨个尝试 ; UIFont *font; ; i < array_length; i++) { font = [font ...

  6. 为什么一款优秀的移动工具类应用必须开发PCclient?

    移动大潮气势汹汹,PC端似乎已经一条腿跨进了坟墓. 作为一个windows开发者.难免有些焦灼. windows真的已死吗?真的无用武之地了吗? 或许是人云亦云吧. 突然看到了这篇文章,感触颇深. 文 ...

  7. vs2008,2010,2012安装包下载

    近期在csdn学院当老师啦.把自己以学到的东西总结一下,录个视频给大家,也当发一下福利.这些以后都是自己无形的財产.哈哈. 安装与下载编程工具 Vs2008下载地址:http://pan.baidu. ...

  8. Windows平台CUDA开发之前的准备工作

    CUDA是NVIDIA的GPU开发工具,眼下在大规模并行计算领域有着广泛应用. windows平台上面的CUDA开发之前.最好去NVIDIA官网查看说明,然后下载对应的driver. ToolKits ...

  9. stm32的pwm波

  10. UE4制作插件的插件神器pluginCreator

    本文章由cartzhang编写,转载请注明出处. 所有权利保留. 文章链接:http://blog.csdn.net/cartzhang/article/details/45644007 作者:car ...