在 C#(或一般的 .NET)中,您可以屏蔽通过属性引发异常的调用堆栈级别吗?
标题可能有点令人困惑,所以我会解释一下。假设您有这个调用链...
public DoWork(index) >> private DoWorkHelper(index) >> private CheckIndex(index)
现在,如果您调用 DoWork
,它会遍历调用直至 CheckIndex
,将每个更深层次的调用添加到调用堆栈中。
现在,如果有人使用 index
的错误值调用 DoWork
,它会在 CheckIndex
处一直抛出异常,目前,这就是调试器中断。然后,您必须返回调用堆栈才能看到真正的罪魁祸首是有人将错误数据传递给了 DoWork
。
现在回到 VB6 时代,您可以简单地用一个属性来装饰 DoWorkHelper
和 CheckIndex
来表示“如果我内部抛出任何异常,不要突出显示我,而是我的来电者是因为他们给我带来了糟糕的废话!因此,在这种情况下,代码将在 DoWork
内部中断,并突出显示对 DoWorkHeper
的调用。
还有一个设置可以禁用此功能,因此为了更深入的调试目的,它仍然可以在 CheckIndex
处抛出,即实际发生的级别,但一半的情况下,在那里崩溃不会告诉你什么,因为你不这样做如果不返回调用堆栈,我不知道你是如何到达那里的。
将其视为一种装饰代码的方法,以便在遇到异常时自动遍历调用堆栈,直到错误值实际上告诉您有用的信息。
请注意,这与“打破所有异常”类似,只是您通过装饰来处理它。另外,您不是设置为在特定类型的异常(例如所有空引用异常等)上中断,而是在特定的方法上中断! (或者更准确地说,是调用修饰方法的方法。)
那么 C# 或 .NET 一般都有这个吗?
更新
虽然我相信 Dark Falcon 给了我答案,因为他指导了我,但我添加了关于所有属性的含义以及在什么上下文中的更详细的解释。看看下面。
The title may be a little confusing so I'll explain. Say you had this call chain...
public DoWork(index) >> private DoWorkHelper(index) >> private CheckIndex(index)
Now if you call DoWork
, it traverses the calls down to CheckIndex
, adding each deeper call to the call stack.
Now if someone calls DoWork
with a bad value for index
, it throws the exception all the way down at CheckIndex
, and currently, that's where the debugger breaks. You then have to walk back up the call stack to see the real offender was that someone passed bad data to DoWork
.
Now back in the VB6 days, you could simply decorate DoWorkHelper
and CheckIndex
with an attribute to say 'If any exception is thrown inside me, don't highlight me, but rather my caller because they were the ones that passed me bad crap!' So in this case, the code would break inside DoWork
with the call to DoWorkHeper
highlighted.
There was also a setting to disable this so for deeper debugging purposes it could still be thrown at CheckIndex
, the level where it actually occurred, but half the time, breaking down there tells you nothing because you don't know how you got there without walking back up the call stack.
Think of it a way to decorate your code to say when you hit an exception, auto-traverse the call stack to the point where the bad value actually tells you something useful.
Note this is similar to 'Break On All Exceptions' except you're handling this via decoration. Plus, you're not setting to break on a specific type of exception (e.g. all null reference exceptions, etc.) but rather a specific method! (or more accurately, the one that called the decorated method.)
So does C# or .NET in general have this?
Update
While I credit Dark Falcon for the answer since he directed me there, I've added a more detailed explanation about what all the attributes mean, and in what context. Check it out below.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
请参阅仅我的代码选项。您需要使用
DebuggerHiddenAttribute
或DebuggerNonUserCodeAttribute
装饰DoWorkHelper
。Please see the Just My Code option. You need to decorate
DoWorkHelper
withDebuggerHiddenAttribute
orDebuggerNonUserCodeAttribute
.只需添加我发现的内容即可更好地解释,这样人们就不必去其他地方寻找...
与此相关的三个属性:
DebuggerHidden
、DebuggerStepThrough
和调试器非用户代码
。规则如下:
当未检查
Just My Code
时:DebuggerNonUserCode
这个基本被忽略了。断点、单步执行和异常的工作方式都相同,就好像该属性不存在一样。
调试器StepThrough
这尊重断点,并且会在发生异常时中断,但您无法手动单步进入标有此属性的块。
隐藏调试器
这不允许您单步执行这些块,它会忽略断点,并且抛出的任何异常都在调用方法中处理,而不是在它们实际发生的地方。
当选中
Just My Code
时,DebuggerHidden
时的行为相同。还有另一个非常酷的属性,
DebuggerStepperBoundary
。以下是 MSDN 的摘录:希望这能解决问题!当然适合我!
Just adding what I've found to better explain so people don't have to go looking elsewhere...
There are three attributes related to this:
DebuggerHidden
,DebuggerStepThrough
, andDebuggerNonUserCode
.Here are the rules:
When
Just My Code
is not checked:DebuggerNonUserCode
This is basically ignored. Breakpoints, step-into and exceptions all work the same as if this attribute wasn't there.
DebuggerStepThrough
This respects breakpoints and will break on exceptions where they occur, but you cannot manually step into blocks marked with this attribute.
DebuggerHidden
This doesn't allow you to step in to these blocks, it ignores breakpoints, and any exceptions thrown are handled in the calling method, not where they actually occur.
When
Just My Code
is checkedDebuggerHidden
above.There's another attribute,
DebuggerStepperBoundary
that is pretty cool. Here's the excerpt from MSDN:Hope this clears things up! Sure did for me!