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

最新文章

  1. VS2010 LINK1123:failure during conversion to COFF:file invalid or corrupt
  2. VS中基于对话框的MFC利用换肤改变边框颜色及格式
  3. bzoj1051
  4. Java远程调试代码不一致问题汇总
  5. 使用Apriori算法和FP-growth算法进行关联分析
  6. Web应用的组件化(一)
  7. HDOJ 1098 Ignatius&#39;s puzzle
  8. [置顶] ios 时间定时器 NSTimer应用demo
  9. Freeplane中的自动边线颜色功能
  10. hashMap_使用
  11. ML笔记:Where does the error come from?
  12. [CQOI 2010]扑克牌
  13. java学习入门之---使用idea创建第一个maven项目
  14. 第四十篇-private,public,protected的区别
  15. Linux什么是挂载?mount的用处在哪?
  16. photoshop cc 2018破解补丁(pscc2018注册机) 附使用方法
  17. 在Unity场景中更改天空盒的步骤
  18. tomcat和java环境
  19. 8.在XamarinAndroid上进一步控制包的大小
  20. Java从零开始学三十八(JAVA IO- 重定向IO)

热门文章

  1. img标签src不给路径就会出现边框
  2. AlertDialog提示对话框练习
  3. 六.基本数据结构-双端队列(Deque)
  4. htmlhomework2
  5. Django中blank和NULL
  6. js获取url制定的某个参数
  7. docker下载容器镜像
  8. HZOJ 巨神兵
  9. python 字典推导式
  10. 【datagrid】动态加载列 2016-01-03 16:32 2013人阅读 评论(19) 收藏