NullReference处于看似无辜的WeakReference访问

本文关键字:WeakReference 访问 无辜 于看似 NullReference | 更新日期: 2023-09-27 18:20:43

所以,我有一段使用WeakReferences的代码。我知道常见的.IsAlive竞赛条件,所以我没有使用它。我基本上有这样的东西:

WeakReference lastString=new WeakReference(null);
public override string ToString()
{
  if(lastString!=null)
  {
    var s=lastString.Target as string; //error here
    if(s!=null)
    {
      return s;
    }
  }
  var str=base.ToString();
  lastString=new WeakReference(str);
  return str;
}

不知怎么的,我在标记的行得到了一个空引用异常。通过调试它,我可以确认lastString确实是null,尽管它被包装在null检查中,并且lastString实际上从未被设置为null。

这种情况也只发生在复杂的流中,这让我认为垃圾收集以某种方式占用了我实际的WeakReference对象,而不仅仅是它的目标。

有人能告诉我这是怎么发生的,最好的行动方案是什么吗?

编辑:我根本无法确定这是什么原因。我最终将错误代码包装在一个try-catch中,现在就修复它。不过,我对这件事的根本原因很感兴趣。我一直试图在一个简单的测试用例中重现这一点,但事实证明这很难做到。此外,这似乎只有在单元测试运行程序下运行时才会发生。如果我把代码修剪到最小,它在使用TestDriven和Gallio运行时会继续崩溃,但在放入控制台应用程序时不会失败

NullReference处于看似无辜的WeakReference访问

这是一个很难发现的逻辑错误,显而易见。

冒犯性的if语句实际上更像这样:

if(lastString!=null && limiter==null || limiter=lastLimiter)

真正的分组更像这样:

if((lastString!=null && limiter==null) || limiter=lastLimiter)

正如Murphy定律所规定的那样,不知何故,在这个不相关的测试用例中,lastLimiterlastString被一个方法设置为null,该方法只在这个测试用例中使用。

是的,CLR中没有任何错误,只是我自己的逻辑错误,很难发现