【问题标题】:C# get object that was on top of stack before exceptionC#获取异常之前位于堆栈顶部的对象
【发布时间】:2012-08-04 13:05:10
【问题描述】:

我正在用 C# 创建一种解释性编程语言(有点像 lulz,除了玩得开心和了解编译器之外没有其他真正的目的),但遇到了问题。在我的词法分析器中,我记得令牌在原始文件中的位置,以提供更有用的调试错误。我保留这个“TokenPosition”对象,在程序通过编译步骤时将其复制,直到它结束在运行解释代码的同一个对象中(例如,我的命名变量的“标识符”类有一个 TokenPosition 成员)。

我的问题:如果抛出异常,我想查看堆栈,找到具有 TokenPosition 成员的最顶层对象,并打印其位置。或者,更一般地说,“我如何获得异常后在堆栈上的对象?这甚至可能吗?” (我可以检查它是否有一个 TokenPosition 对象/很容易得到它,我不是问怎么做)

我不想做的最后手段:每次调用行为(经常发生)都会在 this.tokenPosition 的某处分配一个静态 tokenPosition 变量。我也可以用 try/catch 包围所有内容,但同样,我真的不想这样做。

【问题讨论】:

  • 您的意思是您想知道异常发生时 C# 方法所在的 C# 类,还是您指的是解释器中存在的堆栈?
  • 抛出异常时不恢复堆栈状态会导致解释器无法正常工作。避免过早优化,尝试并不昂贵。使用分析器找到真正的瓶颈。
  • Jon Hanna,我的意思是堆栈上的 C# 对象。不是类型,我知道如何获取类型,我需要堆栈上的对象(或者如果它是静态的,则为 null,无论如何)
  • 该对象甚至可能不再存在,除非您正在做一些事情来抓住它并使其保持活力。如果您正在做某事以保持它并使其保持活力,请使用该代码告诉您它是什么。

标签: c# exception stack


【解决方案1】:

方法的参数是短暂的。当它们不再存在时,它们可能会被局部变量覆盖,或者被 JIT 编译器优化为未使用,甚至是垃圾回收while the method is running。您必须自己跟踪这些信息,例如,通过为“当前活动对象”设置一个单独的堆栈数据结构,该结构会自动由 using 子句展开。

【讨论】:

  • 什么会更快,分配静态“当前位置”变量、try/catch 或 using 语句?加上一个使用“使用”的独特想法。编辑:我刚刚意识到,你在谈论方法,我在谈论方法所在的类。TokenPosition 成员在类内部。
  • 了解的唯一方法是尝试并查看。 (有太多未知数无法一概而论地说明哪个会更快/更容易调试/等等。)
  • 对于那些可能会发现这个问题的人:我可能有缺陷的测试表明 try/catch 比第一个百万的静态分配慢,但对于第二个 for-1- 来说是一样的百万循环我做了,有时更快。在任何一种情况下,100 万次尝试/捕获都不到 0.1 秒,因此对性能的影响不大。我没有测试 using 语句。
猜你喜欢
  • 2013-03-03
  • 2011-06-01
  • 2010-10-19
  • 1970-01-01
  • 1970-01-01
  • 2010-12-08
相关资源
最近更新 更多