WPF 判断调用方法堆栈

原创 2017年10月29日 20:24:04

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

版权声明:http://blog.csdn.net/lindexi_gd 本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

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

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

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

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

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

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

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

/******************************************************** Copyright (c) 2013, binzhouweichao@163.c...

2个堆栈实现自定义队列的入队出队方法 - 调用者定义2个栈的容量

using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace MyQ...

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

Author : Kevin Lynx当软件作为release模式被发布给用户时,当程序崩溃时我们很难去查找原因。常见的手法是输出LOG文件,根据LOG文件分析程序崩溃时的运行情况。我们可以通过SEH...

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

1. 为什么要打印函数调用堆栈?打印调用堆栈可以直接把问题发生时的函数调用关系打出来,非常有利于理解函数调用关系。比如函数A可能被B/C/D调用,如果只看代码,B/C/D谁调用A都有可能,如果打印出调...

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

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

WPF之路——StackPanel布局(堆栈面板)

StackPanel是一个受欢迎的面板,因为它方便好用,它会顺序对它的子元素进行排列。它是少数几个没有定义任何附加属性的面板之一。由于没有附加属性来排列子元素,只有一种方法可以定制StackPanel...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:WPF 判断调用方法堆栈
举报原因:
原因补充:

(最多只允许输入30个字)