WPF 判断调用方法堆栈

2017-11-02 12:56:44来源:http://lindexi.oschina.io/lindexi/post/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)) 有些多余,但是写了也可以


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


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)
{
return true;
}
}
}
return false;
}

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


使用这个方法,可以把调用修改为下面代码


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

感谢walterlv


本文会经常更新,请到原文: https://lindexi.github.io/lindexi/post/WPF-%E5%88%A4%E6%96%AD%E8%B0%83%E7%94%A8%E6%96%B9%E6%B3%95%E5%A0%86%E6%A0%88/ ,避免陈旧错误知识的误导,同时有更好的阅读体验。


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

最新文章

123

最新摄影

闪念基因

微信扫一扫

第七城市微信公众平台