关闭

WPF 判断调用方法堆栈

标签: wpf黑科技
328人阅读 评论(0) 收藏 举报
分类:

最近遇到一个问题,经常有小伙伴在类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 ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请与我联系

0
0
查看评论
发表评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场

Android studio 如何查看正断点函数被那个函数调用

Android studio 如何查看正断点函数被那个函数调用 使用了一段时间android studio开发的今天,我在调试代码时,程序执行到我打断点的函数,真不巧,我那个函数,有很多调用的地方,...
  • bright789
  • bright789
  • 2016-02-27 01:28
  • 2458

VS2015--在 Visual Studio 中调试时映射调用堆栈上的方法

在 Visual Studio 中调试时映射调用堆栈上的方法创建代码图,以便在调试时对调用堆栈进行可视化跟踪。你可以在图中进行标注以跟踪代码执行的操作,以便专注于查找 Bug. 生成调用堆栈图 1...
  • wangshubo1989
  • wangshubo1989
  • 2016-02-29 20:25
  • 11715

底层理解函数调用实现过程 栈结构 栈过程

首先寄存器使用惯例: eip :指令地址寄存器,保存程序计数器的值,当前执行的指令的下一条指令的地址值,16位中为ip,32位为eip。eip不可以直接赋值,一般都是cpu自动加1来更新,指令cal...
  • shiyuqing1207
  • shiyuqing1207
  • 2015-05-31 18:26
  • 1508

OD破解软件找断点方法系列【1】----调用堆栈法

  • 2010-11-24 10:49
  • 1.79MB
  • 下载

华为2014机考题目_判断if括号匹配是否合法_堆栈_简单的方法- -

/******************************************************** Copyright (c) 2013, binzhouweichao@163.c...
  • superweichao
  • superweichao
  • 2013-09-25 17:47
  • 1878

使用dbghelp获取调用堆栈--release下的调试方法学

当软件作为release模式被发布给用户时,当程序崩溃时我们很难去查找原因。常见的手法是输出LOG文件,根据LOG文件分析程序崩溃时的运行情况。我们可以通过SEH来捕获程序错误,然后输出一些有用的信息...
  • weiqubo
  • weiqubo
  • 2012-02-14 22:53
  • 1731

windows平台调用函数堆栈的追踪方法

在windows平台,有一个简单的方法来追踪调用函数的堆栈,就是利用函数CaptureStackBackTrace,但是这个函数不能得到具体调用函数的名称,只能得到地址,当然我们可以通过反汇编的方式通...
  • lanuage
  • lanuage
  • 2016-08-14 12:39
  • 2015

获取iOS任意线程调用堆栈(三)符号化理论:从Mach-o结构分析类名方法名

下面来讲讲如何从Mach-o文件中分析出类名和方法名,也让我们了解下class-dump的原理。 Mach-o结构有两个节:__objc_classname 和 __objc_methname ...
  • jingcheng345413
  • jingcheng345413
  • 2017-05-31 12:25
  • 300

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

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

Android下面打印进程函数调用堆栈(dump backtrace)的方法

1. 为什么要打印函数调用堆栈?打印调用堆栈可以直接把问题发生时的函数调用关系打出来,非常有利于理解函数调用关系。比如函数A可能被B/C/D调用,如果只看代码,B/C/D谁调用A都有可能,如果打印出调...
  • lyl278401555
  • lyl278401555
  • 2016-07-05 10:20
  • 3784
    个人资料
    • 访问:588008次
    • 积分:8745
    • 等级:
    • 排名:第2557名
    • 原创:231篇
    • 转载:16篇
    • 译文:25篇
    • 评论:224条
    博客专栏
    文章分类
    最新评论