NullReference看似无辜的WeakReference访问?

时间:2013-07-02 19:57:55

标签: c# caching weak-references portable-class-library

所以,我有一段使用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,尽管被包装在空检查中并且lastString从未实际设置为null。

这只发生在一个复杂的流程中,这让我觉得垃圾收集以某种方式取得了我的实际WeakReference对象,而不仅仅是它的目标。

有人可以告诉我这是如何发生的以及最佳行动方案是什么?

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

1 个答案:

答案 0 :(得分:1)

这最终成为一个非常难以发现的逻辑错误。

违规if语句真的更像是这样:

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

真正的分组更像是这样:

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

正如Murphy定律所指出的那样,在这个不相关的测试用例中,lastLimiterlastString被一个方法设置为null,而这个方法只用了一个测试用例。

所以,在CLR中没有错误,只是我自己的逻辑错误很难发现