2018-8-10-WPF-判断调用方法堆栈
title | author | date | CreateTime | categories |
---|---|---|---|---|
WPF 判断调用方法堆栈
|
lindexi
|
2018-08-10 19:16:53 +0800
|
2018-2-13 17:23:3 +0800
|
WPF 黑科技
|
最近遇到一个问题,经常有小伙伴在类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 判断调用方法堆栈
<script src='https://gitee.com/lindexi/codes/qigv3dt12js9ywoakpbu631/widget_preview?title=CheckStackClassMethod'></script>
因为传入的类型可能是接口,所以类型判断就需要加上接口继承的,所有代码已经给了大家。
使用这个方法,可以把判断是否在某个类的某个方法调用这个函数就可以修改为下面代码
public void Foo()
{
if (CheckStackClassMethod(typeof(GqpluGkmoanvp), ".d"))
{
Console.WriteLine("构造使用");
}
}
我经过测试下使用这个函数,判断是否我要保护的方法在我不想要被调用的类调用,如果是就抛出异常。接着我的朋友的代码跑不过,就把我祭天。
感谢 walterlv
2018-8-10-WPF-判断调用方法堆栈的更多相关文章
- WPF 判断调用方法堆栈
原文:WPF 判断调用方法堆栈 版权声明:博客已迁移到 http://lindexi.gitee.io 欢迎访问.如果当前博客图片看不到,请到 http://lindexi.gitee.io 访问博客 ...
- XML序列化 判断是否是手机 字符操作普通帮助类 验证数据帮助类 IO帮助类 c# Lambda操作类封装 C# -- 使用反射(Reflect)获取dll文件中的类型并调用方法 C# -- 文件的压缩与解压(GZipStream)
XML序列化 #region 序列化 /// <summary> /// XML序列化 /// </summary> /// <param name="ob ...
- 基于java.util.logging实现轻量级日志记录库(增加根据当前类class初始化,修复线程池模型(javaEE)下的堆栈轨迹顺序与当前调用方法不一致问题)
前言: 本章介绍自己写的基于java.util.logging的轻量级日志记录库(baseLog). 该版本的日志记录库犹如其名,baseLog,是个实现日志记录基本功能的小库,适合小型项目使用,方便 ...
- .netcore 堆栈调用方法小记
背景 上午临近午饭时,公司同事反馈验证码被攻击灌水.我们匆忙查询验证码明细,对已频繁出现的IP插入黑名单,但IP仍然隔断时间频繁变动,不得已之下只能先封禁对应公司id的验证码发送功能.年初时候,专门对 ...
- C#获取当前堆栈的各调用方法列表
在使用.NET编写的代码在debug时很容易进行排查和定位问题,一旦项目上线并出现问题的话那么只能依靠系统日志来进行问题排查和定位,但当项目复杂时,即各种方法间相互调用将导致要获取具体的出错方法或调用 ...
- Delphi按名字调用方法高级解决方案
转帖于https://lfzhs.iteye.com/blog/980200 按名字调用方法似乎一直以来都是大家比较关注的技术,在论坛上有一个经典的答复: type TProcedure = proc ...
- WPF 判断一个对象是否是设计时的窗口类型,而不是运行时的窗口
原文:WPF 判断一个对象是否是设计时的窗口类型,而不是运行时的窗口 当我们对 Window 类型写一个附加属性的时候,在属性变更通知中我们需要判断依赖对象是否是一个窗口.但是,如果直接判断是否是 W ...
- phpcms 的实用相关接口,函数,调用方法
常用函数 , 打开include/global.func.php,下面存放一些公共函数view plaincopy to clipboardprint? strip_tags() 调用内容过滤html ...
- phpcms常用接口调用方法
常用函数 , 打开include/global.func.php,下面存放一些公共函数 view plaincopy to clipboardprint?function str_charset($i ...
随机推荐
- ie8 下margin-top失效的小案例
一个小案例,是关于IE8下的margin-top的失效问题,巨日代码如下: 正常的chrome浏览器下的显示如下: margin-top=10px,正常显示 但是在ie8下,最终样式如下: margi ...
- li设置多选和取消选择的样式、输入数据类型判断
li设置多选和取消选择的样式: $('li').click(function(){ if($(this).hasClass('active')) {$(this).removeClass('activ ...
- Neo4j学习笔记(1)——使用Java API实现简单的增删改查
阅读目录 项目的创建及配置 使用嵌入式数据库 创建节点和关系 查询及更新 删除关系和节点 完整代码 参考资料 回到顶部 项目的创建及配置 因为Neo4j依赖的jar包比较多,所以推荐使用Maven来管 ...
- prepareStatement设置参数,mysql数据出现中文‘?’的情景与解决方式
在prepareStatement中传入中文的参数,mysql数据库中出现“?”号 try { Class.forName("com.mysql.jdbc.Driver"); co ...
- Leetcode811.Subdomain Visit Count子域名访问计数
一个网站域名,如"discuss.leetcode.com",包含了多个子域名.作为顶级域名,常用的有"com",下一级则有"leetcode.com ...
- Length of Last Word输出最后单词的字母个数
Given a string s consists of upper/lower-case alphabets and empty space characters ' ', return the l ...
- lavarel box 地址
https://atlas.hashicorp.com/laravel/boxes/homestead download URL https://atlas.hashicorp.com/laravel ...
- 2019-1-16-win10-uwp-发布的时候-ILC-编译不通过
title author date CreateTime categories win10 uwp 发布的时候 ILC 编译不通过 lindexi 2019-1-16 20:37:5 +0800 20 ...
- @hdu - 6329@ Problem K. Transport Construction
目录 @description@ @solution@ @accepted code@ @details@ @description@ 给定 n 个点,第 i 个点位于 (xi, yi). 在第 i ...
- JavaScript指定周期来调用函数setTimeout和setInterval
setTimeout方法:setTimeout setInterval方法:setInterval