如何在给定时间保持对对象状态的引用?

How can I keep a ref to an object's state at a given time?

我的目标是在引发异常时将调用堆栈状态保存在文件中。但我有一个主要限制:我不能触及任何现有代码。我的目标是在我不知道当前工作流程的情况下实现它。所以我可以在任何 C# 项目中使用它。

为此,我需要有权访问导致异常的所有嵌套方法以及所有方法的参数。

直到现在,我使用 postsharp OnMethodBoundaryAspect,它允许我定义 OnEntry、OnSucess 和 OnException 方法,只要输入方法、returns 或引发异常,就会调用这些方法。很棒的是,我可以在我想要的项目中使用 postsharp.config 文件来应用这个方面。没有源代码修改,我只是将我的项目添加到解决方案、一个配置文件,并在解决方案的每个项目中引用我的项目,我很高兴。使用它,我可以维护自己的调用堆栈,并且可以保存对方法名称的引用,以及对方法参数的引用。

现在假设 methodA 调用 methodB 调用 methodC.

除了显然我使用了引用之外,我所做的一切都很好。因此,如果 methodA 参数在引发异常之前在 methodC 中被修改,当我序列化调用堆栈时,我们将看到一个调用堆栈,其中 methodA 具有错误值的参数(我们将在 methodC).

中看到设置的值

我想解决这个问题,我考虑过使用:

  1. 在 OnEntry 方法中进行深度克隆以复制所有方法参数,但这会导致糟糕的性能
  2. PostSharp LocationInterceptorAspect 但这需要付费许可
  3. VEH Hooking 但它非常慢,使用 deepcloning
  4. 可能会更快

有没有其他方法可以让我以比deepcloning更好的性能及时保存对象的状态,或者至少让我拦截对指定对象的所有修改(比如 VEH挂钩或 LocationInterceptor 方面)?

PS:我不能使用 IOnPropertyChange 或类似的东西,因为我不能触及任何现有的源代码,除非我可以在运行时实现它们但我没有看到任何可能的地方。

考虑到我不想在需要监视的对象中实现任何特定代码,我只有 2 个选项:

  1. 每当需要保存状态时,序列化或任何深度克隆方法(我使用 JSON.NET 作为此解决方案)

  2. 记录对对象的所有修改,以便在必要时撤销它们 => 在进行修改时收到通知我探索了所有这些技术:

    • 带有 LocationInterceptionAspect 的 Postsharp(不是免费的)
    • Harmony 2 允许拦截任何函数调用(在我的例子中是属性的 setter 函数),最简单和最简单的工作解决方案,如果你可以放弃任何字段更改
    • VEH 挂钩,理论上可行,但速度极慢,由于其复杂性,我没有深入研究
    • Editing the MSIL code of a function 挂钩所有 stfld 指令。